Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Catch-All-Feldsuche durch gewichtete Suche in einzelnen Indexfeldern ersetzen #37

Open
j3nsch opened this issue Dec 15, 2021 · 15 comments · May be fixed by #122
Open

Catch-All-Feldsuche durch gewichtete Suche in einzelnen Indexfeldern ersetzen #37

j3nsch opened this issue Dec 15, 2021 · 15 comments · May be fixed by #122
Assignees

Comments

@j3nsch
Copy link
Member

j3nsch commented Dec 15, 2021

Momentan werden für die einfache Suche alle Daten, die berücksichtigt werden sollen, in ein einziges Feld kopiert, die Metadaten und die Volltexte. Dadurch werden die Titel und die Angaben zu den Autoren genauso behandelt wir der Text des Dokuments. Es findet keine Gewichtung statt.

Diese Lösung rührt von ursprünglichen Limitationen in Solr, die mittlerweile nicht mehr bestehen.

Die Suche soll umgestellt werden, um Feldern eine unterschiedliche Gewichtung geben zu können und damit die Suchergebnisse relevanter zu machen.

Intern: https://tickets.zib.de/jira/browse/OPUSVIER-1571

@j3nsch
Copy link
Member Author

j3nsch commented Dec 15, 2021

Auf den ersten Blick sieht es so aus, als ob der aktuelle DisMaxQueryParser ideal wäre.

http://lucene.apache.org/solr/guide/7_3/the-extended-dismax-query-parser.html

Momentan werden eine Vielzahl von Inhalten in unser Suchfeld für die einfache Suche geschrieben. Dementsprechend wird die Liste an Felder, die durchsucht werden sollen, etwas länger sein. Wir müssen prüfen, ob es da vielleicht Probleme gibt. Es müssen Experimente durchgeführt werden.

@j3nsch
Copy link
Member Author

j3nsch commented Dec 15, 2021

Ein Vorteil wäre, dass man dann zum Beispiel die einzelnen Volltext-Extraktionen separat in dynamischen Feldern speichern könnte, so dass evtl. auch erkennbar wäre in welcher Datei ein Stichwort gefunden wurde. Manche Dokumente werden in Repositorien über mehrere PDF-Dateien verteilt gespeichert.

@j3nsch
Copy link
Member Author

j3nsch commented Nov 16, 2023

Wir machen das nur für die PHP 8 Version mit Solr 9.

@j3nsch
Copy link
Member Author

j3nsch commented Nov 16, 2023

Ich frage mich, ob es nicht einfacher ist den Code in opus4-search erst umzubauen, bevor die neue Funktionalität hinzugefügt wird. Im Augenblick ist sehr schwer zu erkennen an welchen Stellen Änderungen vorgenommen werden müssen, um nur die einfache Suche zu ersetzen. Im Prinzip wird aus der "einfachen" Suche, ja eine "komplexe" Suche, bei der der Solr-Request zahlreiche zusätzliche Parameter hat.

@j3nsch
Copy link
Member Author

j3nsch commented Nov 16, 2023

Die Funktion Solr/Solarium/Adapter::applyParametersOnQuery scheint ein guter Kandidat, um herauszufinden, wie die Solarium-Queries manipuliert werden müssen, damit eine Gewichtung verwendet werden kann. Die werden die Informationen aus dem OPUS 4-Query-Objekt auf das Solarium-Query-Objekt übertragen, unter anderem die Liste der Felder (setFields). Es muss in der Solarium-Dokumentation geklärt werden, wie dabei die Gewichtung einzelner Felder berücksichtigt werden kann.

Vielleicht lässt sich das Boosting über zusätzliche Funktionen der Solarium-API hinzufügen, ohne den Rest ändern zu müssen. Die Liste der Felder für die einfache Suche muss sich natürlich verändern. Die Gewichte für die zu durchsuchenden Felder können dann aus der Konfiguration ausgelesen werden.

https://solarium.readthedocs.io/en/stable/queries/select-query/building-a-select-query/components/dismax-component/

Ich denke aber wir können das nicht einfach für alle Suchen machen, sondern erst einmal nur für Simple-Search. Die Informationen sollten also aus dem OPUS 4-Query Objekt kommen, das für die Gewichte erweitert werden muss. Die Information, wenn vorhanden wird dann in applyParametersOnQuery verwendet.

Das sind theoretische Überlegungen. Bei der Umsetzungen können sich weitere Probleme oder bessere Ansätze zeigen.

@j3nsch
Copy link
Member Author

j3nsch commented Nov 16, 2023

Zur (manuellen) Prüfung sollte geschaut werden wie die generierten und an Solr geschickten Queries aussehen. Falls es dafür noch keine guten Debug-Tools gibt, sollte dafür ein weiteres Ticket angelegt werden, um diese Tools zu schaffen. Ein einfache DEBUG-Level logging würde ja erst einmal reichen, wenn es noch nicht vorhanden ist.

@extracts
Copy link
Contributor

Über Solr's defType Query-Parameter lässt sich alternativ zu dem aktuell für "Simple Search" verwendeten Solr Standard Query Parser ein anderer Query Parser (DisMax oder eDisMax) verwenden, welcher eine gewichtete Suche ermöglicht.

Bei der gewichteten Suche lässt sich über den qf Parameter die Gewichtung von Treffern in bestimmten Feldern auf- oder abwerten.

Zusätzlich liesse sich bei einer Suchanfrage mit mehreren Begriffen (z.B. "foo OR bar") die Gewichtung von gefundenen Dokumenten weiter "boosten", indem man das Vorkommen einer exakten Phrase ("foo bar", siehe pf) oder ein benachbartes Vorkommen der Suchbegriffe ("foo baz bar", siehe ps) höher gewichtet. Siehe dazu auch Using 'Slop'.

Weniger relevante Ergebnisse liessen sich bei einer Suchanfrage mit mehreren Begriffen ausschliessen, indem man z.B. vorgibt, dass von drei Suchbegriffen (z.B. "foo OR bar OR baz") mindestens zwei in den gefundenen Dokumenten vorkommen müssen ("foo AND bar" oder "foo AND baz" oder "bar AND baz", siehe mm).

@extracts
Copy link
Contributor

Für eine alternative, gewichtete Suche wäre also nicht unbedingt ein zusätzlicher Endpoint (und Solr RequestHandler) nötig. Dies würde höchstens notwendig sein, wenn man für die gewichtete Suche feste Default-Werte definieren möchte, die selten oder gar nicht in der Konfiguration überschrieben werden. Man kann aber stattdessen auch immer alle Parameter bei der aktuellen Suchanfrage mitgeben.

@j3nsch
Copy link
Member Author

j3nsch commented Nov 16, 2023

Die OPUS 4-Search API enthält das Konzept "NamedSearch" bei denen ein Teil der Suchparameter aus der Konfiguration kommt. Das wurde nie genutzt und soll auch jetzt nicht verwendet werden.

Die zusätzlichen Möglichkeiten die Gewichtung zu steuern, können über die Konfiguration verfügbar gemacht werden, wenn der Aufwand im Augenblick nicht wesentlich ist.

@extracts extracts linked a pull request Nov 16, 2023 that will close this issue
@extracts extracts linked a pull request Nov 16, 2023 that will close this issue
extracts added a commit that referenced this issue Nov 17, 2023
…(using the eDisMax query parser) works as expected
extracts added a commit that referenced this issue Nov 22, 2023
extracts added a commit that referenced this issue Nov 22, 2023
extracts added a commit that referenced this issue Nov 22, 2023
extracts added a commit that referenced this issue Nov 23, 2023
extracts added a commit that referenced this issue Nov 23, 2023
extracts added a commit that referenced this issue Nov 23, 2023
…ng for missing or equal boost factors to a separate test
extracts added a commit that referenced this issue Nov 23, 2023
extracts added a commit that referenced this issue Nov 24, 2023
extracts added a commit that referenced this issue Nov 24, 2023
…ds() which will read the configuration only once
@j3nsch
Copy link
Member Author

j3nsch commented Nov 29, 2023

In der lokalen Konfiguration, config.ini, kann man die Gewichtung für einzelne Felder überschreiben, aber ich denke man kann so kein Feld aus der einfachen Suche herausnehmen.

Mein Vorschlag wäre, eine weitere Option hinzufügen, etwas wie search.searchProfile = default, und search.simple. in search.profile.default. umzubenennen. In lokalen Konfigurationen könnten dann immer noch die Defaultwerte überschrieben werden, aber man könnte auch ein neues "Profil" anlegen mit weniger Feldern. Wenn searchProfile mit einem unbekannten Profilnamen konfiguriert ist oder leer, greift das default-Profile und es gibt eine Meldung ins Log.

Eine alternative Lösung wäre es eine Gewichtung von "0" oder auch "off" als Schalter zu verwenden, um Felder wegzulassen. Das würde ohne Profile funktionieren. Ich denke das sollte zusätzlich und zuerst implementiert werden. Profile sind trotzdem nützlich weil es die Möglichkeit bietet leicht zwischen verschiedenen Konfigurationen umzuschalten, insbesondere für Testzwecke, und der Aufwand sich in vertretbaren Grenzen hält. Später lagern wir Profile vielleicht in separate Dateien aus, die leicht geteilt werden können.

@extracts
Copy link
Contributor

extracts commented Nov 29, 2023

Eine Feld-Gewichtung von "0" wird von Solr standardmässig akzeptiert und weisst einem Dokument mit ausschliesslichem Match in diesem Feld dann entsprechend den Score "0" zu. Falls es für ein Dokument noch Matches in anderen Feldern gibt, so trägt das auf "0" gesetzte Feld auch nicht zum ermittelten Score bei.

Die Liste der zu durchsuchenden Felder wird eigentlich über den Solr Query Parameter fl definiert. Damit müssten sich bestimmte Felder komplett ausschliessen lassen. (Update: fl definiert nur die in der Response zurückgegebenen Felder) Meine Versuche, im Test mal Opus\Search\Query->setFields() zu setzen, schlugen jedoch noch fehl.

@j3nsch
Copy link
Member Author

j3nsch commented Nov 29, 2023

Das besprechen wir im nächsten Meeting. Für die Überlegungen vorab, nur noch folgendes. Es geht darum ein Feld komplett aus der Suche heraus zu nehmen, insbesondere z.B. das Volltextfeld. Das die Gewichtung "0" für Solr ja offensichtlich eine Bedeutung hat, sollte dann ein "off" Wert in der Konfiguration dafür sorgen, dass für das entsprechende Feld keine Gewichtung angegeben wird und das Feld nicht im Query Parameter fl auftaucht. Die Konfiguration der Gewichtungen soll ja auch die Liste der zu durchsuchenden Felder bestimmen. Es klingt so, als ob das noch nicht der Fall ist.

@extracts
Copy link
Contributor

extracts commented Nov 29, 2023

Solr Doku zum Thema:

@j3nsch
Copy link
Member Author

j3nsch commented Nov 29, 2023

Danke für die Links. Ich habe die Seiten kurz überflogen. Bei den Änderungen, die wir machen wollen geht es darum, die einfache Suche in OPUS 4 zu ersetzen. Eine Suche bei der der Nutzer nicht wissen muss wie die Felder im Index heißen. Wir wollen ein einzelnes Feld, dass alles enthält, durch eine Liste von expliziten Feldern für verschiedene Inhalte ersetzen, die unterschiedlich gewichtet werden können. Dabei soll sich für die Nutzer der einfachen Suche nichts ändern. Wie sich dabei die Verwendung von Solr-Query-Syntax auswirkt, müssen wir ausprobieren, aber sie darf nicht notwendig sein. Von außen soll sich nichts ändern, außer einer hoffentlich verbesserten Reihenfolge der Suchergebnisse, nach einem angemessenen Tuning der Gewichtungen.

@extracts
Copy link
Contributor

extracts commented Nov 29, 2023

Ja, das ist mir klar. Aber ich habe bislang keine in allen Fällen funktionierende Lösung gefunden, um mit der gewichteten Suche in mehreren aber nicht allen Feldern zu suchen. Man kann ein StandardFeld (df) angeben, oder OPUS kann die Suchanfrage des Nutzers (z.B. "test") so abändern, dass nur ein einziges Feld wie z.B. das title Feld durchsucht wird ("title:test"). Um gezielt mehrere bestimmte Felder und nur diese (z.B. title & abstract) zu durchsuchen, müsste OPUS ein OR-Query mit "title:test abstract:test" verwenden. Wenn die urspr. Suchanfrage des Nutzers jedoch "test document" lautet, wäre bereits "title:test title:document abstract:test abstract:document" nötig. Ein AND-Query würde hierbei dann aber (im Vergleich zu einer Suche mit "test document" über alle Felder) andere (oder keine) Ergebnisse liefern.

Eine alternative (und mir als einfacher erscheinende) Möglichkeit wäre es, einfach ungewünschte Felder in der Konfig auf "0" zu setzen und beim Verarbeiten der Solr-Ergebnisse (getReturnedMatches()) alle Ergebnisse mit einem Score von "0" herauszufiltern.

extracts added a commit that referenced this issue Nov 29, 2023
…t getWeightedSearch() can load its value from the config if it isn't set yet
extracts added a commit that referenced this issue Nov 29, 2023
extracts added a commit that referenced this issue Dec 1, 2023
…quest parameter that's used when matching phrases
extracts added a commit that referenced this issue Dec 1, 2023
extracts added a commit that referenced this issue Dec 1, 2023
extracts added a commit that referenced this issue Dec 3, 2023
…a; by default, Solr's standard query parser will now only search the "title" field; adopts test accordingly
extracts added a commit that referenced this issue Dec 4, 2023
… default

Setting a field's boost factor to 0 (via the "search.simple" config option) will cause documents with matches just in that field to get a score of 0
extracts added a commit that referenced this issue Dec 4, 2023
…ighted search (which searches across all defined fields instead of just the title field)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: No status
Development

Successfully merging a pull request may close this issue.

2 participants