2013-03-18 5 views
10

Ich versuche, eine einfache Abfrage für zwei bestimmte Felder zu tun, und das Handbuch und Google erweist sich als wenig hilfreich. Beispiel unten sollte es ziemlich klar machen, was ich machen möchte.Eine einfache UND-Abfrage mit Elasticsearch

{ 
    "query": { 
     "and": { 
     "term": { 
      "name.family_name": "daniel", 
      "name.given_name": "tyrone" 
     } 
     } 
    } 
} 

Als Bonus Frage, warum es "Daniel Tyrone" mit "Daniel" findet, aber nicht, wenn ich für "Daniel" zu suchen. Es verhält sich wie eine wirklich seltsame Anti-Case-Sensitive-Suche.

Antwort

9

Bearbeiten: Aktualisiert, sorry. Sie benötigen ein separates Term Objekt für jedes Feld innerhalb eines Bool query:

{ 
    "query": { 
    "bool": { 
     "must" : [ 
      { 
      "term": { 
      "name.family_name": "daniel" 
      } 
     }, 
     { 
      "term": { 
      "name.given_name": "tyrone" 
      } 
     } 
     ] 
    } 
    } 
} 

Zeitabfragen werden nicht durch Elasticsearch analysiert, die sie Groß- und Kleinschreibung macht. Eine Termabfrage sagt zu ES "suchen Sie nach diesem genauen Token in Ihrem Index, einschließlich Groß-/Kleinschreibung und Interpunktion".

Wenn Sie die Groß- und Kleinschreibung nicht berücksichtigen möchten, können Sie Ihrem Analysator einen Schlüsselwort- und Kleinbuchstabenfilter hinzufügen. Alternativ könnten Sie eine Abfrage verwenden, die Ihren Text zur Abfragezeit analysiert (wie eine Match Abfrage)

Edit2: Sie könnten auch And oder Bool-Filter auch verwenden.

+0

Sie meinen Fall sensible Frage falsch verstanden, ich sage es ist wie ein inverser Groß- und Kleinschreibung Suche verhalten, findet es nicht " Daniel "wenn ich mit" Daniel "suche –

+0

Das Beispiel, das du angegeben hast, gibt mir einen Fehler> http://pastium.org/view/c0efa58b6b7689bfff5a9f480c01ed01 –

+0

Gah, tut mir leid. Ich sollte niemals Fragen zu SO vor dem Kaffee beantworten. Ich dachte an den Und-Filter, wenn in Wirklichkeit ES nur die Bool-Abfrage hat. Je nach Anwendungsfall können Sie auch den Bool- oder Und-Filter verwenden. – Zach

2

ich eine Lösung für zumindest mehrere Textvergleiche auf dem gleichen Feld gefunden:

{ 
    "query": { 
    "match": { 
     "name.given_name": { 
     "query": "daniel tyrone", 
     "operator": "and" 
     } 
    } 
    } 

Und ich fand diese für mehrere Felder, dann ist dies der richtige Weg?

{ 
    "query": { 
    "bool": { 
     "must": [   
     { 
      "match": { 
      "name.formatted": { 
       "query": "daniel tyrone", 
       "operator": "and" 
      } 
      } 
     }, 
     { 
      "match": { 
      "display_name": "tyrone" 
      } 
     } 
     ] 
    } 
    } 
} 
+1

Ja, Ihre zweite Abfrage wird funktionieren (vorausgesetzt, Sie möchten, dass 'daniel tyrone' von den Analysegeräten im Feld 'doc' analysiert wird). – Zach

+0

Wenn Sie nicht sicher über die Antwort sind, sollten Sie es nicht als Antwort posten, Sie können es immer als Kommentar zu Ihrer ursprünglichen Frage hinzufügen – tugcem

+0

Endlich habe ich das gefunden!Was macht der Operator in Ihrer ersten Abfrage? Habe ich recht, dass es versuchen wird, eine Wortkombination für given_name zu finden? Mit anderen Worten, given_name sollte wie 'daniel tyrone' aussehen, nicht nur daniel oder tyrone? –

0

Wenn ich den JSON mit PHP zusammensetze, arbeiteten diese 2 Beispiele für mich.

$ activeFilters ist nur ein Komma getrennte Zeichenfolge wie: ‚Attraktionen, limpopo‘

$articles = Article::searchByQuery(array(
     'match' => array(
      'cf_categories' => array(
       'query' => $activeFilters, 
       'operator' =>'and' 
      ) 
     ) 
    )); 

    // The below code is also working 100% 
    // Using Query String https://www.elastic.co/guide/en/elasticsearch/reference/1.4/query-dsl-query-filter.html 
    // https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html 
    /* $articles = Article::searchByQuery(array(
     'query_string' => array(
      'query' => 'cf_categories:attractions AND cf_categories:limpopo' 
     ) 
    )); */