fuer gezieltes Boosting einsetzen
Reines BM25-Scoring kennt nur Textrelevanz, keine Geschaeftsziele. Die Function Score Query schliesst diese Luecke, indem sie den textuellen Score mit zusaetzlichen Faktoren wie Verkaufszahlen, Lagerbestand oder Aktualitaet kombiniert. Wer field_value_factor und Decay-Funktionen beherrscht, kann Suchergebnisse gezielt nach Geschaeftslogik steuern, ohne die textuelle Relevanz zu opfern.
Inhaltsverzeichnis
- 1. Warum reines BM25-Scoring nicht ausreicht
- 2. Grundaufbau der Function Score Query
- 3. field_value_factor: numerische Felder direkt einbeziehen
- 4. Decay-Funktionen: gauss, exp und linear
- 5. boost_mode und score_mode richtig konfigurieren
- 6. Praxisbeispiel: Boosting nach Popularitaet
- 7. Praxisbeispiel: Lagerbestand und Aktualitaet kombinieren
- 8. random_score fuer A/B-Tests und Variation
- 9. Fallstricke beim Einsatz der Function Score Query
- 10. Zusammenfassung
- 11. FAQ
1. Warum reines BM25-Scoring nicht ausreicht
BM25 berechnet Relevanz ausschliesslich aus Textmerkmalen: wie oft ein Suchbegriff vorkommt, wie selten er im Gesamtindex ist und wie lang das durchsuchte Feld ist. Fuer eine reine Textsuche ist das ausreichend, aber im E-Commerce und in vielen anderen Anwendungen spielen weitere Faktoren eine Rolle, die BM25 grundsaetzlich nicht kennt: Verkaufszahlen, Lagerbestand, Kundenbewertung, Aktualitaet oder Marge. Genau hier setzt die Function Score Query an, indem sie den reinen Text-Score um zusaetzliche, frei definierbare Funktionen erweitert.
Die Function Score Query loest ein Problem, das jeder erfahrene Suchentwickler kennt: ein Produkt mit perfekter Textuebereinstimmung, aber seit Monaten ausverkauft, sollte in den meisten Faellen nicht vor einem verfuegbaren, fast ebenso gut passenden Produkt stehen. Ohne zusaetzliches Boosting wuerde BM25 aber genau das tun, weil Verfuegbarkeit fuer den reinen Textalgorithmus keine Rolle spielt.
Die Function Score Query ist deshalb eines der wichtigsten Werkzeuge, um aus einer rein textuell relevanten Suche eine geschaeftlich sinnvolle Suche zu machen. Sie kombiniert eine Basis-Query, meist eine Bool Query mit Match- und Filter-Klauseln, mit einer Liste von Funktionen, die den urspruenglichen Score modifizieren, verstaerken oder daempfen.
2. Grundaufbau der Function Score Query
Strukturell besteht eine Function Score Query aus zwei Hauptteilen: der query, die den textuellen Basis-Score liefert, und dem Array functions, das eine Liste von Boosting-Funktionen enthaelt. Jede Funktion in diesem Array kann optional an einen eigenen filter gebunden sein, sodass sie nur auf Dokumente angewendet wird, die diesen Filter erfuellen. Ohne eigenen Filter wirkt eine Funktion auf alle Dokumente der Ergebnismenge.
Der finale Score eines Dokuments entsteht in zwei Schritten: zuerst werden die Ergebnisse aller Funktionen ueber den Parameter score_mode zu einem einzigen Funktions-Score kombiniert, zum Beispiel durch Summierung, Multiplikation oder Mittelwertbildung. Anschliessend wird dieser Funktions-Score mit dem urspruenglichen Query-Score ueber den Parameter boost_mode verknuepft, ebenfalls waehlbar zwischen Multiplikation, Summe, Maximum und weiteren Optionen. Dieses zweistufige System gibt volle Kontrolle darueber, wie stark Geschaeftsfaktoren die textuelle Relevanz beeinflussen duerfen.
Ein haeufiger Anwendungsfall der Function Score Query ist es, die Basis-Query eine normale Bool Query mit Match- und Filter-Klauseln sein zu lassen, waehrend die Funktionen ausschliesslich fuer feines Boosting zustaendig sind. Diese Trennung zwischen "was ist relevant" und "was soll zusaetzlich gewichtet werden" haelt die Konfiguration nachvollziehbar, auch wenn mehrere Funktionen gleichzeitig aktiv sind.
GET /products/_search
{
"query": {
"function_score": {
"query": {
"match": { "title": "laufschuhe" }
},
"functions": [
{
"field_value_factor": {
"field": "sales_count",
"modifier": "log1p",
"factor": 0.5
}
}
],
"boost_mode": "sum",
"score_mode": "sum"
}
}
}
// The BM25 text score is added to a boost derived from sales_count
// modifier log1p prevents runaway scores from very high sales numbers
3. field_value_factor: numerische Felder direkt einbeziehen
Die field_value_factor-Funktion ist die direkteste Art, ein numerisches Feld in den Score einzubeziehen. Sie liest den Wert eines Feldes, etwa Verkaufszahlen oder Kundenbewertung, multipliziert ihn optional mit einem factor und wendet optional einen modifier an, bevor das Ergebnis in den Gesamt-Score einfliesst. Ohne modifier wuerde ein Feldwert von 10000 den Score um den Faktor 10000 verzerren, was praktisch nie gewuenscht ist.
Der Modifier log1p berechnet den natuerlichen Logarithmus von 1 + Feldwert und daempft dadurch grosse Werte deutlich staerker als kleine, was fuer Verkaufszahlen oder Klickzahlen fast immer die richtige Wahl ist: der Unterschied zwischen 10 und 100 Verkaeufen soll spuerbar sein, der Unterschied zwischen 10000 und 10090 Verkaeufen praktisch nicht. Andere verfuegbare Modifier sind sqrt fuer eine mildere Daempfung und log2p fuer eine staerkere.
Wichtig bei field_value_factor ist der Umgang mit fehlenden oder null-wertigen Feldern: standardmaessig wirft Elasticsearch einen Fehler, wenn das referenzierte Feld bei einem Dokument fehlt. Der Parameter missing definiert einen Ersatzwert fuer diesen Fall und sollte in produktiven Konfigurationen immer gesetzt werden, um Laufzeitfehler bei unvollstaendigen Daten zu vermeiden.
GET /products/_search
{
"query": {
"function_score": {
"query": { "match_all": {} },
"functions": [
{
"field_value_factor": {
"field": "rating",
"factor": 1.2,
"modifier": "sqrt",
"missing": 1
}
}
],
"boost_mode": "multiply"
}
}
}
// missing: 1 provides a fallback for documents without a rating field
// sqrt dampens the impact of ratings less aggressively than log1p
4. Decay-Funktionen: gauss, exp und linear
Waehrend field_value_factor monoton mit dem Feldwert steigt, gibt es Anwendungsfaelle, in denen die Relevanz mit zunehmendem Abstand von einem Referenzpunkt abnehmen soll, statt linear zu steigen. Dafuer bietet die Function Score Query drei Decay-Funktionen: gauss, exp und linear. Alle drei nehmen einen origin-Wert, einen scale-Wert und optional einen decay-Wert und berechnen daraus, wie stark der Score mit zunehmendem Abstand vom Referenzpunkt sinkt.
Der klassische Anwendungsfall fuer Decay-Funktionen ist Aktualitaet: ein neu veroeffentlichter Artikel oder ein neu eingetroffenes Produkt soll einen Relevanz-Bonus bekommen, der mit zunehmendem Alter abnimmt, aber nicht abrupt auf null faellt. Mit gauss auf dem Feld published_date, origin auf das aktuelle Datum und scale auf beispielsweise 30 Tage erhalten Artikel der letzten Wochen einen sanft abklingenden Bonus, waehrend sehr alte Artikel kaum noch profitieren.
Der Unterschied zwischen den drei Decay-Funktionen liegt in der Form der Abklingkurve: gauss faellt zunaechst langsam und dann schneller ab, exp faellt von Anfang an exponentiell, linear faellt gleichmaessig bis zum Wert null bei der doppelten scale-Distanz. Fuer geografische Naehe, zum Beispiel Boosting von Filialen oder Lagerstandorten nahe der Nutzerposition, sind Decay-Funktionen ebenfalls das Standardwerkzeug, angewendet auf ein geo_point-Feld statt auf ein Datumsfeld.
GET /articles/_search
{
"query": {
"function_score": {
"query": { "match": { "content": "elasticsearch update" } },
"functions": [
{
"gauss": {
"published_date": {
"origin": "now",
"scale": "30d",
"decay": 0.5
}
}
}
],
"boost_mode": "multiply"
}
}
}
// Articles published 30 days ago retain 50% of the freshness boost
// the gaussian curve fades gently, older articles score progressively lower
5. boost_mode und score_mode richtig konfigurieren
Der Parameter score_mode bestimmt, wie mehrere Funktionsergebnisse innerhalb der Function Score Query zu einem einzigen Funktions-Score kombiniert werden. Optionen sind unter anderem multiply (Standard), sum, avg, max, min und first. Bei mehreren Funktionen, die jeweils an einen eigenen Filter gebunden sind, ist first besonders nuetzlich, weil nur das Ergebnis der ersten zutreffenden Funktion verwendet wird, was sich fuer sich gegenseitig ausschliessende Kategorien eignet.
Der Parameter boost_mode bestimmt, wie dieser kombinierte Funktions-Score mit dem urspruenglichen Query-Score verrechnet wird. multiply ist der Standard und eignet sich gut, wenn der Funktions-Score als relativer Verstaerker wirken soll. sum eignet sich, wenn Textrelevanz und Geschaeftsfaktoren additiv gleichberechtigt einfliessen sollen. replace ignoriert den Query-Score komplett und verwendet ausschliesslich den Funktions-Score, was fuer reine Sortier-Anwendungsfaelle ohne Textsuche sinnvoll sein kann.
Ein haeufiger Konfigurationsfehler ist die Wahl von multiply als boost_mode, ohne die Funktionswerte vorher zu normalisieren. Ein Funktions-Score von 0 multipliziert den Gesamt-Score auf null und entfernt das Dokument effektiv aus sinnvollen Rankingpositionen, selbst wenn die Textrelevanz hoch war. Der Parameter min_score auf Funktionsebene oder ein sorgfaeltig gewaehlter missing-Wert verhindert dieses Problem zuverlaessig.
6. Praxisbeispiel: Boosting nach Popularitaet
Ein typisches E-Commerce-Szenario kombiniert Textrelevanz mit Verkaufszahlen und Kundenbewertung in einer einzigen Function Score Query. Die Basis-Query sucht nach dem Produkttitel, waehrend zwei field_value_factor-Funktionen Verkaufszahlen und Bewertung einbeziehen. Beide Funktionswerte werden ueber score_mode: "sum" addiert und anschliessend ueber boost_mode: "multiply" mit dem Text-Score verrechnet, sodass ein Produkt ohne jede Textuebereinstimmung trotz hoher Popularitaet nicht in den Ergebnissen erscheint.
Diese Struktur stellt sicher, dass Popularitaet die Reihenfolge innerhalb der textuell relevanten Ergebnisse beeinflusst, aber niemals ein vollstaendig irrelevantes Produkt in die Trefferliste zieht. Genau dieses Verhalten unterscheidet die Function Score Query von einer reinen Sortierung nach Popularitaet: die Textrelevanz bleibt die Eintrittsbarriere, das Boosting wirkt nur innerhalb der bereits relevanten Treffer.
| Funktion | Einsatzzweck | Typisches Feld |
|---|---|---|
| field_value_factor | Numerische Werte direkt gewichten | sales_count, rating, margin |
| gauss | Sanft abklingender Bonus um einen Punkt | published_date, geo_point |
| exp | Schneller abklingender Bonus | published_date, event_date |
| linear | Gleichmaessig abklingender Bonus | price, distance |
| random_score | Kontrollierte Zufallsvariation | A/B-Tests, Ergebnis-Diversitaet |
7. Praxisbeispiel: Lagerbestand und Aktualitaet kombinieren
Ein zweites praxisnahes Beispiel kombiniert drei Funktionen: eine filter-gebundene Funktion, die Produkte ohne Lagerbestand mit einem festen niedrigen weight abstraft statt sie ganz auszuschliessen, eine field_value_factor-Funktion fuer Verkaufszahlen und eine gauss-Decay-Funktion fuer die Aktualitaet des Produkteintrags. Diese Kombination erlaubt, ausverkaufte Produkte weiterhin sichtbar zu halten, etwa fuer Interessenten, die eine Benachrichtigung bei Wiederverfuegbarkeit einrichten koennen, ohne sie in den Top-Ergebnissen zu platzieren.
Der Vorteil, ausverkaufte Produkte ueber ein niedriges Gewicht statt ueber einen harten Filter zu behandeln, liegt in der Flexibilitaet: sollte sich herausstellen, dass Nutzer trotzdem an diesen Produkten interessiert sind, laesst sich das Gewicht anpassen, ohne die Filterlogik komplett zu aendern. Diese Flexibilitaet ist einer der groessten praktischen Vorteile der Function Score Query gegenueber starren Filterregeln in der Bool Query.
GET /products/_search
{
"query": {
"function_score": {
"query": { "match": { "title": "laufschuhe" } },
"functions": [
{
"filter": { "term": { "in_stock": false } },
"weight": 0.1
},
{
"field_value_factor": {
"field": "sales_count",
"modifier": "log1p",
"missing": 0
}
},
{
"gauss": {
"updated_at": { "origin": "now", "scale": "60d" }
}
}
],
"score_mode": "sum",
"boost_mode": "multiply"
}
}
}
// Out-of-stock products get a heavy 0.1 weight penalty, not full exclusion
// sales and freshness combine additively before multiplying the text score
8. random_score fuer A/B-Tests und Variation
Die Funktion random_score fuegt dem Score eine kontrollierte, aber deterministische Zufallskomponente hinzu, basierend auf einem Seed-Wert. Anders als echter Zufall liefert derselbe Seed bei jeder Anfrage dieselbe Reihenfolge, was fuer konsistente Paginierung wichtig ist, waehrend unterschiedliche Seeds unterschiedliche Nutzer oder Sitzungen unterschiedliche Ergebnisreihenfolgen sehen lassen koennen. Das ist besonders nuetzlich fuer A/B-Tests von Ranking-Aenderungen oder um bei sehr aehnlich bewerteten Produkten kuenstliche Diversitaet in die Trefferliste zu bringen.
In der Praxis wird random_score selten alleine verwendet, sondern meist mit einem niedrigen Gewicht zu einer bestehenden Function Score Query hinzugefuegt, um bei ansonsten identischen Scores eine leichte, aber reproduzierbare Variation zu erzeugen. Ohne diese Massnahme wuerden Produkte mit identischem Score immer in derselben, oft durch die Dokument-ID bestimmten Reihenfolge erscheinen, was auf Dauer zu einer wahrgenommenen Bevorzugung einzelner Produkte fuehren kann.
Mironsoft
Elasticsearch- und OpenSearch-Suchloesungen fuer anspruchsvolle Datenmengen
Suchergebnisse, die eure Geschaeftsziele ignorieren?
Wir konfigurieren Function Score Queries, die Popularitaet, Lagerbestand und Aktualitaet gezielt in die Suchrelevanz einbringen, ohne die textuelle Praezision zu opfern.
Boosting-Strategie
field_value_factor und Decay-Funktionen fuer euer Sortiment definieren
Konfiguration
boost_mode und score_mode fuer eure Geschaeftslogik korrekt kalibrieren
A/B-Testing
random_score und Ranking-Varianten fuer datengetriebene Entscheidungen aufsetzen
9. Fallstricke beim Einsatz der Function Score Query
Der haeufigste Fallstrick ist unnormalisiertes Boosting: ein Feld mit sehr grossem Wertebereich, etwa Verkaufszahlen zwischen 0 und 100000, dominiert ohne Modifier und Faktor den gesamten Score und macht die textuelle Relevanz praktisch irrelevant. Die Loesung ist konsequente Verwendung von Modifiern wie log1p und sorgfaeltig gewaehlten factor-Werten, idealerweise anhand realer Datenverteilung getestet, nicht nach Gefuehl geschaetzt.
Ein zweiter Fallstrick betrifft Performance: jede zusaetzliche Funktion in einer Function Score Query, besonders Decay-Funktionen auf grossen Datensaetzen, kostet zusaetzliche Rechenzeit pro Dokument. Bei sehr grossen Indizes mit vielen gleichzeitigen Suchanfragen sollte die Anzahl der Funktionen bewusst klein gehalten und regelmaessig auf tatsaechlichen Business-Impact ueberprueft werden, statt Funktionen "auf Verdacht" zu ergaenzen. Ein dritter Fallstrick ist das Fehlen von missing-Werten bei field_value_factor, was bei unvollstaendigen Daten zu Laufzeitfehlern statt zu sinnvollen Fallback-Werten fuehrt.
10. Zusammenfassung
Die Function Score Query erweitert den reinen BM25-Text-Score um frei definierbare Funktionen, die Geschaeftssignale wie Popularitaet, Lagerbestand oder Aktualitaet einbeziehen. field_value_factor gewichtet numerische Felder direkt, meist gedaempft durch einen Modifier wie log1p. Decay-Funktionen wie gauss, exp und linear erzeugen einen mit zunehmendem Abstand von einem Referenzpunkt abklingenden Bonus, klassischerweise fuer Aktualitaet oder geografische Naehe.
Die Parameter score_mode und boost_mode steuern, wie mehrere Funktionen kombiniert und mit dem urspruenglichen Text-Score verrechnet werden, wobei unnormalisiertes Boosting der haeufigste Konfigurationsfehler ist. Richtig eingesetzt, erlaubt die Function Score Query, Textrelevanz als Eintrittsbarriere zu behalten, waehrend Geschaeftsfaktoren die Feinsortierung innerhalb der relevanten Treffer uebernehmen, ein Muster, das fast jede produktive E-Commerce-Suche in irgendeiner Form nutzt.
Function Score Query fuer Boosting, das Wichtigste auf einen Blick
field_value_factor
Numerische Felder direkt einbeziehen, mit log1p oder sqrt daempfen, missing-Wert setzen.
Decay-Funktionen
gauss, exp und linear fuer sanft abklingende Boni, klassisch fuer Aktualitaet und geografische Naehe.
boost_mode und score_mode
Steuern, wie Funktionen kombiniert und mit dem Text-Score verrechnet werden. Sorgfaeltig kalibrieren.
Haeufigster Fehler
Unnormalisiertes Boosting dominiert die Textrelevanz. Immer mit Modifier und getesteten Faktoren arbeiten.