Carian teks penuh dengan Solr

1. Gambaran keseluruhan

Dalam artikel ini, kita akan meneroka konsep asas dalam enjin carian Apache Solr - carian teks penuh.

Apache Solr adalah kerangka sumber terbuka, yang dirancang untuk menangani berjuta-juta dokumen. Kami akan membahas kemampuan terasnya dengan contoh menggunakan perpustakaan Java - SolrJ.

2. Konfigurasi Maven

Memandangkan fakta bahawa Solr adalah sumber terbuka - kami hanya boleh memuat turun perduaan dan memulakan pelayan secara berasingan dari aplikasi kami.

Untuk berkomunikasi dengan pelayan, kami akan menentukan pergantungan Maven untuk klien SolrJ:

 org.apache.solr solr-solrj 6.4.2 

Anda boleh mendapatkan pergantungan terkini di sini.

3. Pengindeksan Data

Untuk mengindeks dan mencari data, kita perlu membuat inti ; kami akan membuat satu item bernama untuk mengindeks data kami.

Sebelum melakukan itu, kita memerlukan data yang akan diindeks di pelayan, sehingga dapat dicari.

Terdapat banyak cara untuk mengindeks data. Kita dapat menggunakan pengendali import data untuk mengimport data secara langsung dari pangkalan data relasional, memuat naik data dengan Solr Cell menggunakan Apache Tika atau memuat naik data XML / XSLT, JSON dan CSV menggunakan pengendali indeks.

3.1. Dokumen Solr Pengindeksan

Kita dapat mengindeks data menjadi inti dengan membuat SolrInputDocument . Pertama, kita perlu mengisi dokumen dengan data kita dan kemudian memanggil API SolrJ untuk mengindeks dokumen:

SolrInputDocument doc = new SolrInputDocument(); doc.addField("id", id); doc.addField("description", description); doc.addField("category", category); doc.addField("price", price); solrClient.add(doc); solrClient.commit();

Perhatikan bahawa id semestinya unik untuk item yang berbeza . Memiliki id dokumen yang sudah diindeks akan mengemas kini dokumen tersebut.

3.2. Kacang Indeks

SolrJ menyediakan API untuk mengindeks kacang Java. Untuk mengindeks kacang, kita perlu memberikannya dengan anotasi @Field :

public class Item { @Field private String id; @Field private String description; @Field private String category; @Field private float price; }

Sebaik sahaja kita mempunyai kacang, pengindeksan lurus ke hadapan:

solrClient.addBean(item); solrClient.commit();

4. Pertanyaan Solr

Mencari adalah keupayaan Solr yang paling kuat. Setelah dokumen diindeks di repositori kami, kami dapat mencari kata kunci, frasa, julat tarikh, dan lain-lain. Hasilnya disusun mengikut kesesuaian (skor).

4.1. Pertanyaan Asas

Pelayan mendedahkan API untuk operasi carian. Kita boleh memanggil / memilih atau / menangani permintaan permintaan.

Mari buat carian mudah:

SolrQuery query = new SolrQuery(); query.setQuery("brand1"); query.setStart(0); query.setRows(10); QueryResponse response = solrClient.query(query); List items = response.getBeans(Item.class);

SolrJ secara dalaman akan menggunakan parameter pertanyaan utama q dalam permintaannya ke pelayan. Bilangan rekod yang dikembalikan akan menjadi 10, diindeks dari sifar ketika permulaan dan baris tidak ditentukan.

Pertanyaan carian di atas akan mencari sebarang dokumen yang mengandungi kata lengkap "brand1" di mana-mana bidangnya yang diindeks. Perhatikan bahawa carian mudah tidak peka huruf besar kecil.

Mari lihat contoh lain. Kami ingin mencari mana-mana perkataan yang mengandungi "rand" , yang dimulai dengan sebilangan watak dan berakhir dengan hanya satu watak. Kita boleh menggunakan watak wildcard * dan ? dalam pertanyaan kami:

query.setQuery("*rand?");

Pertanyaan Solr juga menyokong operator boolean seperti di SQL:

query.setQuery("brand1 AND (Washing OR Refrigerator)");

Semua operator boolean mesti berada dalam huruf besar; yang disokong oleh penghurai pertanyaan adalah DAN , ATAU, TIDAK , + dan -.

Lebih-lebih lagi, jika kita ingin mencari pada bidang tertentu dan bukannya semua bidang yang diindeks, kita dapat menentukannya dalam pertanyaan:

query.setQuery("description:Brand* AND category:*Washing*");

4.2. Pertanyaan Frasa

Hingga tahap ini, kod kami mencari kata kunci dalam bidang yang diindeks. Kami juga boleh melakukan carian frasa pada bidang yang diindeks:

query.setQuery("Washing Machine");

Apabila kita mempunyai frasa seperti " Mesin Cuci ", penghurai pertanyaan standard Solr menguraikannya menjadi " Mesin Cuci ATAU ". Untuk mencari keseluruhan frasa, kita hanya dapat menambahkan ungkapan dalam tanda petik ganda:

query.setQuery("\"Washing Machine\"");

Kita boleh menggunakan carian jarak untuk mencari kata-kata dalam jarak tertentu . Sekiranya kita ingin mencari perkataan yang sekurang-kurangnya dua perkataan terpisah, kita boleh menggunakan pertanyaan berikut:

query.setQuery("\"Washing equipment\"~2");

4.3. Pertanyaan Julat

Pertanyaan jarak jauh membolehkan mendapatkan dokumen yang bidangnya berada di antara julat tertentu.

Katakan kita mahu mencari item yang harganya berkisar antara 100 hingga 300:

query.setQuery("price:[100 TO 300]");

Pertanyaan di atas akan menemui semua elemen yang harganya antara 100 hingga 300, termasuk. Kita dapat menggunakan " } " dan " { " untuk mengecualikan titik akhir:

query.setQuery("price:{100 TO 300]");

4.4. Tapis Pertanyaan

Pertanyaan tapisan boleh digunakan untuk menyekat superset hasil yang dapat dikembalikan. Pertanyaan tapisan tidak mempengaruhi skor:

SolrQuery query = new SolrQuery(); query.setQuery("price:[100 TO 300]"); query.addFilterQuery("description:Brand1","category:Home Appliances");

Secara amnya, pertanyaan penapis akan mengandungi pertanyaan yang biasa digunakan. Oleh kerana mereka sering digunakan semula, mereka disimpan dalam cache untuk menjadikan carian lebih cekap.

5. Carian Berwajah

Faceting helps to arrange search results into group counts. We can facet fields, query or ranges.

5.1. Field Faceting

For example, we want to get the aggregated counts of categories in the search result. We can add category field in our query:

query.addFacetField("category"); QueryResponse response = solrClient.query(query); List facetResults = response.getFacetField("category").getValues();

The facetResults will contain counts of each category in the results.

5.2. Query Faceting

Query faceting is very useful when we want to bring back counts of subqueries:

query.addFacetQuery("Washing OR Refrigerator"); query.addFacetQuery("Brand2"); QueryResponse response = solrClient.query(query); Map facetQueryMap = response.getFacetQuery();

As a result, the facetQueryMap will have counts of facet queries.

5.3. Range Faceting

Range faceting is used to get the range counts in the search results. The following query will return the counts of price ranges between 100 and 251, gapped by 25:

query.addNumericRangeFacet("price", 100, 275, 25); QueryResponse response = solrClient.query(query); List rangeFacets = response.getFacetRanges().get(0).getCounts();

Apart from numeric ranges, Solr also supports date ranges, interval faceting, and pivot faceting.

6. Hit Highlighting

We may want the keywords in our search query to be highlighted in the results. This will be very helpful to get a better picture of the results. Let's index some documents and define keywords to be highlighted:

itemSearchService.index("hm0001", "Brand1 Washing Machine", "Home Appliances", 100f); itemSearchService.index("hm0002", "Brand1 Refrigerator", "Home Appliances", 300f); itemSearchService.index("hm0003", "Brand2 Ceiling Fan", "Home Appliances", 200f); itemSearchService.index("hm0004", "Brand2 Dishwasher", "Washing equipments", 250f); SolrQuery query = new SolrQuery(); query.setQuery("Appliances"); query.setHighlight(true); query.addHighlightField("category"); QueryResponse response = solrClient.query(query); Map
    
     > hitHighlightedMap = response.getHighlighting(); Map
     
       highlightedFieldMap = hitHighlightedMap.get("hm0001"); List highlightedList = highlightedFieldMap.get("category"); String highLightedText = highlightedList.get(0);
     
    

We'll get the highLightedText as “Home Appliances. Please notice that the search keyword Appliances is tagged with . Default highlighting tag used by Solr is , but we can change this by setting the pre and post tags:

query.setHighlightSimplePre(""); query.setHighlightSimplePost("");

7. Search Suggestions

One of the important features that Solr supports are suggestions. If the keywords in the query contain spelling mistakes or if we want to suggest to autocomplete a search keyword, we can use the suggestion feature.

7.1. Spell Checking

The standard search handler does not include spell checking component; it has to be configured manually. There are three ways to do it. You can find the configuration details in the official wiki page. In our example, we'll use IndexBasedSpellChecker, which uses indexed data for keyword spell checking.

Let's search for a keyword with spelling mistake:

query.setQuery("hme"); query.set("spellcheck", "on"); QueryResponse response = solrClient.query(query); SpellCheckResponse spellCheckResponse = response.getSpellCheckResponse(); Suggestion suggestion = spellCheckResponse.getSuggestions().get(0); List alternatives = suggestion.getAlternatives(); String alternative = alternatives.get(0);

Expected alternative for our keyword “hme” should be “home” as our index contains the term “home”. Note that spellcheck has to be activated before executing the search.

7.2. Auto Suggesting Terms

We may want to get the suggestions of incomplete keywords to assist with the search. Solr's suggest component has to be configured manually. You can find the configuration details in its official wiki page.

We have configured a request handler named /suggest to handle suggestions. Let's get suggestions for keyword “Hom”:

SolrQuery query = new SolrQuery(); query.setRequestHandler("/suggest"); query.set("suggest", "true"); query.set("suggest.build", "true"); query.set("suggest.dictionary", "mySuggester"); query.set("suggest.q", "Hom"); QueryResponse response = solrClient.query(query); SuggesterResponse suggesterResponse = response.getSuggesterResponse(); Map
      
        suggestedTerms = suggesterResponse.getSuggestedTerms(); List suggestions = suggestedTerms.get("mySuggester");
      

The list suggestions should contain all words and phrases. Note that we have configured a suggester named mySuggester in our configuration.

8. Conclusion

This article is a quick intro to the search engine's capabilities and features of Solr.

We touched on many features, but these are of course just scratching the surface of what we can do with an advanced and mature search server such as Solr.

The examples used here are available as always, over on GitHub.