Volltextsuche mit Solr

Volltextsuche mit Solr

1. Überblick

In diesem Artikel untersuchen wir ein grundlegendes Konzept in der Suchmaschine vonApache Solr- die Volltextsuche.

The Apache Solr is an open source framework, designed to deal with millions of documents. Wir werden die Kernfunktionen anhand von Beispielen unter Verwendung der Java-Bibliothek -SolrJ durchgehen.

2. Maven-Konfiguration

Angesichts der Tatsache, dass Solr Open Source ist, können wir einfach die Binärdatei herunterladen und den Server separat von unserer Anwendung starten.

Um mit dem Server zu kommunizieren, definieren wir die Maven-Abhängigkeit für den SolrJ-Client:


    org.apache.solr
    solr-solrj
    6.4.2

Sie finden die neuesten Abhängigkeitenhere.

3. Daten indizieren

Um Daten zu indizieren und zu suchen, müssen wircore erstellen. Wir erstellen einitem, um unsere Daten zu indizieren.

Zuvor müssen die Daten auf dem Server indiziert werden, damit sie durchsucht werden können.

There are many different ways we can index data. Wir können Datenimport-Handler verwenden, um Daten direkt aus relationalen Datenbanken zu importieren, Daten mit Solr Cell mithilfe von Apache Tika hochzuladen oder XML / XSLT-, JSON- und CSV-Daten mithilfe von Index-Handlern hochzuladen.

3.1. Indizieren von Solr-Dokumenten

Wir können Daten incore indizieren, indem wirSolrInputDocument erstellen. Zuerst müssen wir das Dokument mit unseren Daten füllen und dann nur die SolrJ-API aufrufen, um das Dokument zu indizieren:

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();

Beachten Sie, dassid natürlich für verschiedeneitems eindeutig sein sollte. Wenn Sie einid eines bereits indizierten Dokuments haben, wird dieses Dokument aktualisiert.

3.2. Bohnen indizieren

SolrJ bietet APIs zum Indizieren von Java-Beans. Um eine Bean zu indizieren, müssen wir sie mit den Annotationen von@Fieldversehen:

public class Item {

    @Field
    private String id;

    @Field
    private String description;

    @Field
    private String category;

    @Field
    private float price;
}

Sobald wir die Bohne haben, ist die Indizierung einfach:

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

4. Solr-Abfragen

Suchen ist die leistungsstärkste Funktion von Solr. Sobald wir die Dokumente in unserem Repository indiziert haben, können wir nach Schlüsselwörtern, Phrasen, Datumsbereichen usw. suchen. Die Ergebnisse sind nach Relevanz (Score) sortiert.

4.1. Grundlegende Abfragen

Der Server macht eine API für Suchvorgänge verfügbar. Wir können entweder/select oder/query Anforderungshandler aufrufen.

Lassen Sie uns eine einfache Suche durchführen:

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 verwendet intern den Hauptabfrageparameterq in seiner Anforderung an den Server. Die Anzahl der zurückgegebenen Datensätze beträgt 10 und wird von Null indiziert, wennstart undrows nicht angegeben sind.

Die obige Suchabfrage sucht nach Dokumenten, die das vollständige Wort“brand1” in einem der indizierten Felder enthalten. Beachten Sie, dasssimple searches are not case sensitive.

Let’s look at another example. Wir möchten jedes Wort suchen, das“rand” enthält, das mit einer beliebigen Anzahl von Zeichen beginnt und mit nur einem Zeichen endet. In unserer Abfrage können Platzhalterzeichen* und? verwendet werden:

query.setQuery("*rand?");

Solr-Abfragen unterstützen auch Boolesche Operatoren wie in SQL:

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

Alle booleschen Operatoren müssen in Großbuchstaben angegeben werden. Diejenigen, die vom Abfrageparser unterstützt werden, sindAND,OR, NOT,+ und -.

Wenn wir statt aller indizierten Felder nach bestimmten Feldern suchen möchten, können wir diese in der Abfrage angeben:

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

4.2. Phrasenabfragen

Bis zu diesem Zeitpunkt suchte unser Code in den indizierten Feldern nach Schlüsselwörtern. Wir können auch nach Phrasen in den indizierten Feldern suchen:

query.setQuery("Washing Machine");

Wenn wir eine Phrase wie "Washing Machine" haben, analysiert Solrs Standard-Abfrageparser sie in "Washing OR Machine". Um nach einer ganzen Phrase zu suchen, können wir den Ausdruck nur in doppelten Anführungszeichen einfügen:

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

We can use proximity search to find words within specific distances. Wenn wir die Wörter suchen möchten, die mindestens zwei Wörter voneinander entfernt sind, können wir die folgende Abfrage verwenden:

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

4.3. Bereichsabfragen

Bereichsabfragen ermöglichen das Abrufen von Dokumenten, deren Felder zwischen bestimmten Bereichen liegen.

Nehmen wir an, wir möchten Artikel finden, deren Preis zwischen 100 und 300 liegt:

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

Die obige Abfrage findet alle Elemente, deren Preis zwischen 100 und 300 einschließlich liegt. Wir können "}" und "\{" verwenden, um Endpunkte auszuschließen:

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

4.4. Abfragen filtern

Filterabfragen können verwendet werden, um die Obermenge der zurückgegebenen Ergebnisse einzuschränken. Filterabfrage hat keinen Einfluss auf die Bewertung:

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

Im Allgemeinen enthält die Filterabfrage häufig verwendete Abfragen. Da sie häufig wiederverwendbar sind, werden sie zwischengespeichert, um die Suche effizienter zu gestalten.

Facettierung hilft, Suchergebnisse in Gruppen zu ordnen. Wir können Felder, Abfragen oder Bereiche facettieren.

5.1. Feldfacettierung

Beispielsweise möchten wir die aggregierte Anzahl von Kategorien im Suchergebnis erhalten. Wir könnencategory Feld in unsere Abfrage einfügen:

query.addFacetField("category");

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

DiefacetResults enthalten Zählungen jeder Kategorie in den Ergebnissen.

5.2. Facettierung abfragen

Das Facettieren von Abfragen ist sehr nützlich, wenn die Anzahl der Unterabfragen zurückgesetzt werden soll:

query.addFacetQuery("Washing OR Refrigerator");
query.addFacetQuery("Brand2");

QueryResponse response = solrClient.query(query);
Map facetQueryMap = response.getFacetQuery();

Infolgedessen werden infacetQueryMap Facettenabfragen gezählt.

5.3. Range Facettierung

Die Bereichsfacettierung wird verwendet, um die Bereichszählungen in den Suchergebnissen abzurufen. Die folgende Abfrage gibt die Anzahl der Preisbereiche zwischen 100 und 251 zurück, die um 25 voneinander abweichen:

query.addNumericRangeFacet("price", 100, 275, 25);

QueryResponse response = solrClient.query(query);
List rangeFacets =  response.getFacetRanges().get(0).getCounts();

Neben numerischen Bereichen unterstützt Solr auch Datumsbereiche, Intervall-Facettierung und Pivot-Facettierung.

6. Klicken Sie auf Hervorheben

Möglicherweise möchten wir, dass die Keywords in unserer Suchanfrage in den Ergebnissen hervorgehoben werden. Dies ist sehr hilfreich, um ein besseres Bild der Ergebnisse zu erhalten. Lassen Sie uns einige Dokumente indizieren und Schlüsselwörter definieren, die hervorgehoben werden sollen:

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);

Wir erhalten diehighLightedText als“Home <em>Appliances</em>”. Bitte beachten Sie, dass das SuchwortAppliances mit<em> gekennzeichnet ist. Das von Solr verwendete Standard-Hervorhebungs-Tag ist<em>. Sie können dies jedoch ändern, indem Sie die Tagspre undpost festlegen:

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

7. Suchvorschläge

Eines der wichtigsten Merkmale, die Solr unterstützt, sind Vorschläge. Wenn die Schlüsselwörter in der Abfrage Rechtschreibfehler enthalten oder wir vorschlagen möchten, ein Suchschlüsselwort automatisch zu vervollständigen, können wir die Vorschlagsfunktion verwenden.

7.1. Rechtschreibprüfung

Die Standard-Suchroutine enthält keine Komponente zur Rechtschreibprüfung. es muss manuell konfiguriert werden. Es gibt drei Möglichkeiten, dies zu tun. Die Konfigurationsdetails finden Sie in den offiziellenwiki page. In unserem Beispiel verwenden wirIndexBasedSpellChecker, das indizierte Daten für die Rechtschreibprüfung von Schlüsselwörtern verwendet.

Suchen wir nach einem Schlüsselwort mit Rechtschreibfehlern:

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);

Die erwartete Alternative für unser Schlüsselwort“hme” sollte“home” sein, da unser Index den Begriff“home”. enthält. Beachten Sie, dassspellcheck vor dem Ausführen der Suche aktiviert werden muss.

7.2. Begriffe automatisch vorschlagen

Möglicherweise möchten wir Vorschläge für unvollständige Keywords erhalten, um die Suche zu erleichtern. Die von Solr vorgeschlagene Komponente muss manuell konfiguriert werden. Sie finden die Konfigurationsdetails in den offiziellenwiki page.

Wir haben einen Anforderungshandler mit dem Namen/suggest konfiguriert, um Vorschläge zu verarbeiten. Lassen Sie uns Vorschläge für das Schlüsselwort“Hom” erhalten:

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");

Die Listesuggestions sollte alle Wörter und Phrasen enthalten. Beachten Sie, dass wir in unserer Konfiguration einen Suggester mit dem NamenmySuggester konfiguriert haben.

8. Fazit

Dieser Artikel ist eine kurze Einführung in die Funktionen und Merkmale der Suchmaschine von Solr.

Wir haben viele Funktionen angesprochen, aber diese sind natürlich nur ein Kratzer an der Oberfläche dessen, was wir mit einem fortschrittlichen und ausgereiften Suchserver wie Solr machen können.

Die hier verwendeten Beispiele sind wie immer verfügbar,over on GitHub.