2017-11-28 7 views
2

Ich benutze Solr 6.6.0, und hier sind die Dokumente in der Sammlung.Negativer Operator (NOT, -,!) Im Solr-Abfrage-String funktioniert nicht mit Klammern

{"id":1,"content":test1"} 
{"id":2,"content":test2"} 
{"id":3,"content":test3"} 

Sagen wir, ich wanto die Dokumente nicht enthalten „Test1“ und „Test2“ enthält, scheint es legal, die Query-String in der folgenden Art und Weise zu schreiben, nach dem Grouping Terms to Form Sub-Queries Abschnitt refernce Führung.

content:((NOT "test1") AND (NOT "test2")) 

Das Ergebnis der Abfrage ist die erwartete Rückkehr nur Dokument # 3, aber das tatsächliche Ergebnis ist leer.

Wenn die obige Abfrage geändert wird, ohne dass Klammern die "NOT-Ausdrücke" umgeben, wird das erwartete Ergebnis zurückgegeben.

Meine Frage ist, warum der erste Abfrage-String nicht in der erwarteten Weise funktioniert?

Antwort

2

Solr sucht derzeit nach einer "reinen negativen" Abfrage und fügt *:* ein (die allen Dokumenten entspricht), so dass das letztere Format (das ohne Klammern) korrekt funktioniert.

Sehen Sie den Code-Snippet unten aus org.apache.solr.search.QueryUtils.java

/** Fixes a negative query by adding a MatchAllDocs query clause. 
    * The query passed in *must* be a negative query. 
    */ 
public static Query fixNegativeQuery(Query q) { 
    BooleanQuery newBq = (BooleanQuery)q.clone(); 
    newBq.add(new MatchAllDocsQuery(), BooleanClause.Occur.MUST); 
    return newBq; 
} 

So NOT "test" von solr in (*:* NOT "test")

Aber Solr nur die Top-Level-Abfrage überprüft nur transformiert wird, Das bedeutet, dass eine Abfrage wie (NOT "test1") nicht geändert wird, da die reine negative Abfrage nicht in der obersten Ebene ist. Deshalb funktioniert das frühere Format (das mit Klammern) nicht wie erwartet.

So können wir schließen, dass im Allgemeinen die richtige Art und Weise NOT Betreiber der Verwendung ist die (*:* NOT some_expression) Form, anstelle einer einzigen NOT some_expression.

+0

Gute Antwort! Beachten Sie, dass dies auch funktionieren sollte: '-content :(" test1 "ODER" test2 ")' Das ist äquivalent zu '*: * NOT content :(" test1 "ODER" test2 ")', äquivalent zu '*: * UND Inhalt: (NICHT "test1" UND NICHT "test2") ' – EricLavault

Verwandte Themen