Blog_allgemein

SurroundQueryParser

Johannes Brucher

…ist nicht nur auf dem Gebiet Search & Analytics Spezialist, sondern fühlt sich ebenso im Bereich SHI Publishing Solutions zuhause. Geboren 1981 in Bayern, studierte er Bioinformatik mit Schwerpunkt Softwareengineering an der FH Weihenstephan in Freising. Seit über 10 Jahren bereichert er SHI mit seinen Fachkenntnissen, die er bei SHI von „Junior Consultant“ zum „Senior Technical Consultant“ ausbaute. Lieblings-Dateiformat: WAV, MOV, jar

In Solr 4.0 wurde nicht nur die SolrCloud eingeführt. Es gab auch abseits davon zahlreiche Neuerungen, darunter einige QueryParser.

In diesem Beitrag wird nun der SurroundQueryParser vorgestellt, der es ermöglicht Wörter, die im Text nah beieinander stehen, zu matchen. Das bedeutet, er kann alternativ zum eDismax QueryParser mit den Parametern pf und ps benutzt werden. Diese beiden Möglichkeiten werden im Folgenden nun näher beleuchtet und gegenüber gestellt.

Folgend ist ein Beispielaufruf des SurroundQueryParsers aufgelistet:

https://localhost:8983/solr/collection1/select?q={!surround v=$qq}&df=body
&qq=8n(here, forecast)&fl=body

Erläuterung der Parameter
qq=8n(here, forecast)

Lokale Variable qq, der eine Query zugewiesen wird. Die Query benutzt spezifische Syntax. 8n bedeutet eine Suche nach den beiden in Klammern stehenden Termen, bei der die Reihenfolge der Terme keine Rolle spielt. Diese dürfen eine Distanz von acht voneinander aufweisen. Soll die Reihenfolge der Terme berücksichtigt werden, benutzt man w statt n:

qq=8w(here, forecast)
q={!surround v=$qq}

In diesem Parameter wird der QParser definiert (!surround) und die Query (v=$qq). Es wird die eingangs definierte Variable qq als Query übergeben.

Die restlichen Parameter haben mit dem SurroundQueryParser speziell nichts zu tun. df=body bedeutet, dass im Feld body gesucht wird, fl=body bedeutet, dass nur das Feld body angezeigt werden soll.

Ein „Übersetzen“ der Query, sodass der eDismax als QParser verwendet wird, sieht dann wie folgt aus:

https://localhost:8983/solr/collection1/select?q=here forecast&qf=body
&fl=body&defType=edismax&pf=body&ps=8

Erläuterung der Parameter:

qf=body gibt hier das Feld an, in dem gesucht werden soll. fl=body legt wieder body als anzuzeigendes Feld fest. Der QParser wird nun mit dem defType Parameter definiert. Für die Phrasensuche kommen nun die Parameter pf (gibt das Feld an, welches für die Suche nach der Phrase als Quelle genommen werden soll) und ps(gibt den Abstand zwischen den beiden Suchbegriffen an) ins Spiel.

Vergleicht man die beiden Methoden ist folgendes zu beachten:

  • Verwendet man den eDismax QParser werden alle Dokumentegefunden, die einen der beiden Suchterme beinhalten, als Treffer zurückgegeben, wenn Suchterme per Default mit OR verknüpft werden. Beim SurroundQueryParser nur diejenigen, die die Suchterme auch als Phrase mit definiertem Abstand zueinander haben.
  • Es gibt jeweils mehrere Möglichkeiten, die QParser zu definieren bzw. auszuwählen. Ein äquivalenter Aufruf zu obigem SurroundQueryParser-Aufruf wäre folgender:
    localhost:8983/solr/collection1/select?q=8n%28here,%20forecast%29&defType=surround&df=body&debugQuery=true
    Hier wird nicht mehr die localParams-Schreibweise verwendet.
  • Der Score wird unterschiedlich berechnet. Folgende Ausschnitte sollen dies verdeutlichen.

pf & ps Parameter (nur der Ausschnitt der Phrase):

2.050164 = (MATCH) weight(body:"here forecast"~8 in 0) [DefaultSimilarity], result of:

2.050164 = score(doc=0,freq=0.33333334 = phraseFreq=0.33333334

), product of:

0.80350405 = queryWeight, product of:

8.838757 = idf(), sum of:

3.0372834 = idf(docFreq=67462, maxDocs=517424)

5.801473 = idf(docFreq=4251, maxDocs=517424)

0.09090691 = queryNorm

2.5515292 = fieldWeight in 0, product of:

0.57735026 = tf(freq=0.33333334), with freq of:

0.33333334 = phraseFreq=0.33333334

8.838757 = idf(), sum of:

3.0372834 = idf(docFreq=67462, maxDocs=517424)

5.801473 = idf(docFreq=4251, maxDocs=517424)

0.5 = fieldNorm(doc=0)

SurroundQueryParser (Berechnung des kompletten Scores):

1.976406 = (MATCH) weight(spanNear([body:here, body:forecast], 7, false) in 0) [DefaultSimilarity], result of:

1.976406 = fieldWeight in 0, product of:

0.4472136 = tf(freq=0.2), with freq of:

0.2 = phraseFreq=0.2

8.838757 = idf(), sum of:

5.801473 = idf(docFreq=4251, maxDocs=517424)

3.0372834 = idf(docFreq=67462, maxDocs=517424)

0.5 = fieldNorm(doc=0)

Obwohl unter Umständen wesentlich mehr Dokumente bei der Benutzung des eDismax QueryParser gefunden werden, geht die Tendenz bei der Verwendung natürlich in dessen Richtung. Hier ist die Phrase kein exklusives Suchkriterium, aber ein sehr wertvoller Faktor bei der Score-Berechnung. Der SurroundQueryParser kann natürlich bei erweiterten Suchen eingesetzt werden, bei denen die Benutzer ihre Suchparameter genau eingeben können.