Cerca con Typesense per Laravel Scout

Utilizzo di Typesense come provider di ricerca per Laravel Scout e Instantsearch.

Senso tipografico è un'ottima alternativa open source per AlgoliaDato che Algolia ha un pacchetto prezzi piuttosto costoso, potrebbe valere la pena dare un'occhiata a Typesense.

Oltre a ciò, ha già alcune integrazioni con pacchetti famosi come Ricerca istantanea.js E Esploratore Laravel.

È iniziato di recente, quindi la documentazione è ancora carente di alcuni esempi. Ecco perché ho scritto questo post:

Utilizzo di Typesense per Laravel

La cosa grandiosa è che è disponibile un pacchetto Laravel Scout: https://github.com/devloopsnet/laravel-scout-typesense-engine

Correggere i primi errori Typesense con Laravel:

Molto probabilmente, riceverai degli errori quando utilizzi le impostazioni predefinite come descritto nel pacchetto Typesense Laravel Scout:

{"message": "Il campo `id` del documento dovrebbe essere una stringa."}

Questo problema può essere risolto convertendo l'ID in una stringa nell'array ricercabile:

/** * Ottieni l'array di dati indicizzabili per il modello. * * @return array */ public function toSearchableArray() { $array = $this->toArray();
   // Specifico del senso del tipo
   se (config('scout.driver') == 'typesensesearch') {
      $array['id'] = (stringa)$array['id']; $array['created_at'] = (intero)\Carbon::parse($array['created_at'])->timestamp;
   }
   restituisci $array;
}

Da notare che ho anche convertito il valore datetime created_at in un timestamp intero, in modo che Typesense potesse ordinare facilmente in base al valore intero della data.

🤓😎 Sempre più persone stanno ricevendo i nostri consigli su Geek, Privacy, Sviluppo e Stile di Vita

Vuoi ricevere gli ultimi blog su Geek, Privacy, Sviluppo e Lifestyle? Iscriviti alla nostra newsletter.

Aggiunta dell'adattatore Instantsearch.js Typesense a Laravel

Puoi seguire i passaggi descritti dal Istruzioni per l'adattatore Typesense. Inoltre non dimenticare di installare npm algoliasearch e instantsearch.js .

Inserimento in Laravel Mix

Puoi inserire il seguente codice nel file webpack.mix.js per Laravel Mix:

mix.extract(['algoliasearch', 'instantsearch.js', 'typesense-instantsearch-adapter']) .js(['resources/js/app.js'], 'public/js');

Prepara anche le importazioni nel tuo resources/js/app.js:

importa instantsearch da "instantsearch.js"; window.instantsearch = instantsearch; importa { searchBox, hits, index } da "instantsearch.js/es/widgets"; window.searchBox = searchBox; window.hits = hits; window.index = index; importa { connectAutocomplete } da 'instantsearch.js/es/connectors'; window.connectAutocomplete = connectAutocomplete; importa TypesenseInstantSearchAdapter da "typesense-instantsearch-adapter"; window.TypesenseInstantSearchAdapter = TypesenseInstantSearchAdapter;

Nota che ho incluso anche index e connectAutocomplete che sono necessari per il widget Autocomplete. Se non hai intenzione di usarli, puoi ometterli.

Esegui Laravel Mix con (usa anche npm install se Mix non è mai stato inizializzato):

npm esegui sviluppo

Nel file blade del layout principale aggiungi i file mix generati:

Quindi puoi semplicemente inserire i risultati e la casella di ricerca:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/themes/reset-min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/themes/algolia-min.css">


<div id="hits"></div>
<div id="searchbox"></div>

<script>
const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter({
  server: {
    apiKey: "{{ env('TYPESENSE_SEARCH_KEY') }}", // Be sure to use the search-only-api-key
    nodes: [
      {
        host: "{{ env('TYPESENSE_HOST') }}",
        port: "443",
        protocol: "https"
      }
    ]
  },
  // The following parameters are directly passed to Typesense's search API endpoint.
  //  So you can pass any parameters supported by the search endpoint below. 
  //  queryBy is required. 
  additionalSearchParameters: {
    queryBy: "name"
  }
});
const searchClient = typesenseInstantsearchAdapter.searchClient;

const search = instantsearch({
  searchClient,
  indexName: "products"
});

// Create the custom widget
const customAutocomplete = connectAutocomplete(
  renderAutocomplete
);

// Instantiate the custom widget
search.addWidgets([
  index({ searchClient, indexName: 'autolandings' }),

  customAutocomplete({
    container: document.querySelector('#autocomplete'),
  })
]);

search.start();
</script>

Ho aggiunto il tema CSS di instantsearch.js per dargli un po' di stile di base. Questo non sembra funzionare ancora per Autocomplete. Devi dare tu stesso uno stile completo a questo (per quanto ne so).

Come utilizzare Instantsearch.js Autocomplete con Typesense

Typesense ha scritto un adattatore che funziona con Ricerca istantanea.js per Algolia. Ha alcuni esempi di base per utilizzare i componenti hits e searchBox.

In alcuni casi potresti voler estendere questa funzionalità. Ad esempio, se desideri utilizzare il Completamento automatico Instantsearch.js funzionalità devi scrivere codice aggiuntivo. Per creare una funzionalità di autocompletamento di base con più indici puoi usare questo codice:

Utilizzo di più indici e completamento automatico per Instantsearch.js

In questo esempio ho copiato il codice dal sito web Instantsearch.js Autocomplete di Algolia e ho integrato l'adattatore Typesense:

<div id="autocomplete"></div>

<script>
const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter({
  server: {
    apiKey: "{{ env('TYPESENSE_SEARCH_KEY') }}", // Be sure to use the search-only-api-key
    nodes: [
      {
        host: "{{ env('TYPESENSE_HOST') }}",
        port: "443",
        protocol: "https"
      }
    ]
  },
  // The following parameters are directly passed to Typesense's search API endpoint.
  //  So you can pass any parameters supported by the search endpoint below. 
  //  queryBy is required. 
  additionalSearchParameters: {
    queryBy: "name"
  }
});
const searchClient = typesenseInstantsearchAdapter.searchClient;

const search = instantsearch({
  searchClient,
  indexName: "products"
});

// Helper for the render function
const renderIndexListItem = ({ indexId, hits }) => `
  <li>
    Index: ${indexId}
    <ol>
      ${hits
        .map(
          (hit, hitIndex) =>
            `
              <li>
                <p>${instantsearch.highlight({ attribute: 'name', hit })}</p>
                <button
                  type="button"
                  class="btn-add-to-cart"
                  data-index-id="${indexId}"
                  data-hit-index="${hitIndex}"
                >
                  Add to Cart
                </button>
              </li>
            `
        )
        .join('')}
    </ol>
  </li>
`;

// Create the render function
const renderAutocomplete = (renderOptions, isFirstRender) => {
  const { indices, currentRefinement, refine, widgetParams } = renderOptions;

  if (isFirstRender) {
    const input = document.createElement('input');
    const ul = document.createElement('ul');

    input.addEventListener('input', event => {
      refine(event.currentTarget.value);
    });

    widgetParams.container.appendChild(input);
    widgetParams.container.appendChild(ul);

    ul.addEventListener('click', (event) => {
      if (event.target.className === 'btn-add-to-cart') {
        const indexId = event.target.getAttribute('data-index-id');
        const hitIndex = event.target.getAttribute('data-hit-index');
        const index = indices.find(index => index.indexId === indexId);
        const hit = index.hits[hitIndex];

        index.sendEvent('conversion', hit, 'Product Added');
      }
    });
  }

  widgetParams.container.querySelector('input').value = currentRefinement;
  widgetParams.container.querySelector('ul').innerHTML = indices
    .map(renderIndexListItem)
    .join('');
};

// Create the custom widget
const customAutocomplete = connectAutocomplete(
  renderAutocomplete
);

// Instantiate the custom widget
search.addWidgets([
  index({ searchClient, indexName: 'landings' }),

  customAutocomplete({
    container: document.querySelector('#autocomplete'),
  })
]);

search.start();
</script>

Non dimenticare di compilare TYPESENSE_SEARCH_KEY e TYPESENSE_HOST nelle tue variabili di ambiente. E sostituisci i primi prodotti indice con l'indice desiderato. Sostituisci 'landings' con il secondo indice desiderato. Puoi aggiungere altri indici aggiungendo:

indice({ searchClient, nomeindice: 'anotherIndex' }),

alla parte search.AddWidgets.

Tieni presente che dobbiamo importare anche il connettore di completamento automatico e il widget del componente indice tramite Laravel Mix.

Ultimo aggiornamento l'8 ottobre 2020

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

it_ITItaliano
Scorri verso l'alto