2014-01-16 19 views
7

Ich habe einen Index wie folgende Einstellungen und Zuordnung;Elasticsearch Wildcard Suche auf not_analyzed Feld

{ 
    "settings":{ 
    "index":{ 
     "analysis":{ 
      "analyzer":{ 
       "analyzer_keyword":{ 
       "tokenizer":"keyword", 
       "filter":"lowercase" 
       } 
      } 
     } 
    } 
    }, 
    "mappings":{ 
    "product":{ 
     "properties":{ 
      "name":{ 
       "analyzer":"analyzer_keyword", 
       "type":"string", 
       "index": "not_analyzed" 
      } 
     } 
    } 
    } 
} 

Ich kämpfe um eine Implementierung für Wildcard-Suche auf name Feld mit zu machen. Meine Beispieldaten so;

[ 
{"name": "SVF-123"}, 
{"name": "SVF-234"} 
] 

Wenn ich folgende Abfrage durchführen;

http://localhost:9200/my_index/product/_search -d ' 
{ 
    "query": { 
     "filtered" : { 
      "query" : { 
       "query_string" : { 
        "query": "*SVF-1*" 
       } 
      } 
     } 

    } 
}' 

Es gibt SVF-123, SVF-234. Ich denke, es tunkiert immer noch Daten. Es muss nur SVF-123 zurückgegeben werden.

Könnten Sie bitte dabei helfen?

Vielen Dank im Voraus

+0

FYI, die Sie nicht wirklich eine führende Wildcard wollen, ich denke, es bei jedem doc aussehen wird, wenn Sie das tun. – mconlin

+0

Ich kenne den Defekt auf der Leistung, aber ich muss Wildcard-Suche sogar SVF- * –

+0

Ich denke Trailing Wildcards ist in Ordnung, Sie wollen einfach nicht die führende .. – mconlin

Antwort

11

Meine Lösung Abenteuer

Ich habe meinen Fall begann, wie Sie in meiner Frage sehen können. Immer wenn ich einen Teil meiner Einstellungen geändert habe, hat ein Teil angefangen zu arbeiten, aber ein anderer Teil hört auf zu arbeiten. Lassen Sie mich meine Lösungshistorie geben:

1.) Ich habe meine Daten als Standard indiziert. Das bedeutet, dass meine Daten standardmäßig analyzed sind. Dies wird Probleme auf meiner Seite verursachen. Beispielsweise;

Wenn Benutzer ein Schlüsselwort wie SVF-1, System ausführen, um diese Abfrage zu suchen begann:

{ 
    "query": { 
     "filtered" : { 
      "query" : { 
       "query_string" : { 
        "analyze_wildcard": true, 
        "query": "*SVF-1*" 
       } 
      } 
     } 

    } 
} 

und Ergebnisse;

SVF-123 
SVF-234 

Das ist normal, weil name Bereich meiner Dokumente analyzed sind. Dies teilt die Abfrage in Tokens SVF und 1, und SVF entspricht meinen Dokumenten, obwohl 1 nicht übereinstimmt. Ich habe diesen Weg ausgelassen.Ich habe eine Zuordnung erstellen für meine Felder sie machen not_analyzed

{ 
    "mappings":{ 
    "product":{ 
     "properties":{ 
      "name":{ 
       "type":"string", 
       "index": "not_analyzed" 
      }, 
      "site":{ 
       "type":"string", 
       "index": "not_analyzed" 
      } 
     } 
    } 
    } 
} 

aber mein Problem fortgesetzt.

2.) Ich wollte nach viel Forschung einen anderen Weg versuchen. Beschlossen, wildcard query zu verwenden. Meine Abfrage ist;

{ 
    "query": { 
     "wildcard" : { 
      "name" : { 
       "value" : *SVF-1*" 
      } 
      } 
     }, 
      "filter":{ 
        "term": {"site":"pro_en_GB"} 
      } 
    } 
} 

Diese Abfrage funktionierte, aber ein Problem hier. Meine Felder werden nicht mehr analysiert, und ich mache eine Platzhalterabfrage. Groß-/Kleinschreibung ist hier ein Problem. Wenn ich wie svf-1 suche, gibt es nichts zurück. Da kann Benutzer Kleinbuchstaben Version der Abfrage eingeben.

3.) Ich habe meine Dokumentstruktur geändert;

{ 
    "mappings":{ 
    "product":{ 
     "properties":{ 
      "name":{ 
       "type":"string", 
       "index": "not_analyzed" 
      }, 
      "nameLowerCase":{ 
       "type":"string", 
       "index": "not_analyzed" 
      } 
      "site":{ 
       "type":"string", 
       "index": "not_analyzed" 
      } 
     } 
    } 
    } 
} 

Ich habe ein weiteres Feld adde für namenameLowerCase genannt. Wenn ich mein Dokument indexiere, setze ich mein Dokument wie;

{ 
    name: "SVF-123", 
    nameLowerCase: "svf-123", 
    site: "pro_en_GB" 
} 

Hier, ich bin Umwandlung Abfrage Schlüsselwort in Kleinbuchstaben und Suchoperation auf neue nameLowerCase Index zu machen. Und Anzeige name Feld.

Endgültige Version meiner Abfrage ist;

{ 
    "query": { 
     "wildcard" : { 
      "nameLowerCase" : { 
       "value" : "*svf-1*" 
      } 
      } 
     }, 
      "filter":{ 
        "term": {"site":"pro_en_GB"} 
      } 
    } 
} 

Jetzt funktioniert es. Es gibt auch eine Möglichkeit, dieses Problem zu lösen, indem Sie multi_field verwenden. Meine Abfrage enthält Bindestrich (-) und einige Probleme.

Vielen Dank an @ Alex Brasetvik für seine ausführliche Erklärung und Mühe

12

Es gibt ein paar Dinge schief geht hier vor.

Erstens, Sie sagen, dass Sie nicht wollen, analysiert Indexzeit. Dann gibt es einen konfigurierten Analysator (der die Suchzeit verwendet), der inkompatible Terme generiert. (Sie sind klein)

Standardmäßig enden alle Begriffe im Feld _all mit dem Standardanalysator. Dort suchst du am Ende. Da es auf "-" steht, erhalten Sie ein ODER von "* SVF" und "1 *".

Versuchen Sie eine Terme Facette auf _all und auf Name zu tun, um zu sehen, was los ist.

Hier ist ein lauffähiges Spiel und Kern: https://www.found.no/play/gist/3e5fcb1b4c41cfc20226 (https://gist.github.com/alexbrasetvik/3e5fcb1b4c41cfc20226)

Sie müssen sicherstellen, dass die Bedingungen Sie Index mit kompatibel ist, was Sie suchen. Sie möchten wahrscheinlich _all deaktivieren, da es schlammig ist, was vor sich geht.

#!/bin/bash 

export ELASTICSEARCH_ENDPOINT="http://localhost:9200" 

# Create indexes 

curl -XPUT "$ELASTICSEARCH_ENDPOINT/play" -d '{ 
    "settings": { 
     "analysis": { 
      "text": [ 
       "SVF-123", 
       "SVF-234" 
      ], 
      "analyzer": { 
       "analyzer_keyword": { 
        "type": "custom", 
        "tokenizer": "keyword", 
        "filter": [ 
         "lowercase" 
        ] 
       } 
      } 
     } 
    }, 
    "mappings": { 
     "type": { 
      "properties": { 
       "name": { 
        "type": "string", 
        "index": "not_analyzed", 
        "analyzer": "analyzer_keyword" 
       } 
      } 
     } 
    } 
}' 


# Index documents 
curl -XPOST "$ELASTICSEARCH_ENDPOINT/_bulk?refresh=true" -d ' 
{"index":{"_index":"play","_type":"type"}} 
{"name":"SVF-123"} 
{"index":{"_index":"play","_type":"type"}} 
{"name":"SVF-234"} 
' 

# Do searches 

# See all the generated terms. 
curl -XPOST "$ELASTICSEARCH_ENDPOINT/_search?pretty" -d ' 
{ 
    "facets": { 
     "name": { 
      "terms": { 
       "field": "name" 
      } 
     }, 
     "_all": { 
      "terms": { 
       "field": "_all" 
      } 
     } 
    } 
} 
' 

# Analyzed, so no match 
curl -XPOST "$ELASTICSEARCH_ENDPOINT/_search?pretty" -d ' 
{ 
    "query": { 
     "match": { 
      "name": { 
       "query": "SVF-123" 
      } 
     } 
    } 
} 
' 

# Not analyzed according to `analyzer_keyword`, so matches. (Note: term, not match) 
curl -XPOST "$ELASTICSEARCH_ENDPOINT/_search?pretty" -d ' 
{ 
    "query": { 
     "term": { 
      "name": { 
       "value": "SVF-123" 
      } 
     } 
    } 
} 
' 


curl -XPOST "$ELASTICSEARCH_ENDPOINT/_search?pretty" -d ' 
{ 
    "query": { 
     "term": { 
      "_all": { 
       "value": "svf" 
      } 
     } 
    } 
} 
' 
+0

Zuerst, danke für Ihre Antwort. Ich habe Ihre Beispiele verwendet, aber es hat nicht für meinen Fall funktioniert. Mein Fall ist ein bisschen kompliziert. Schließlich habe ich eine Lösung gefunden und werde in meiner Antwort den ganzen Fall angeben. –

0

zu Hüseyin Antwort hinzufügen, können wir und als Standard-Operator verwenden. Also werden SVF und 1 * mit dem Operator AND verknüpft, was uns die richtigen Ergebnisse liefert.

"query": { 
    "filtered" : { 
     "query" : { 
      "query_string" : { 
       "default_operator": "AND", 
       "analyze_wildcard": true, 
       "query": "*SVF-1*" 
      } 
     } 
    } 
} 
0

@Viduranga Wijesooriya wie angegeben Sie "default_operator" : "AND" für Vorhandensein von sowohl SVF überprüfen wird und 1, aber genaue Übereinstimmung allein ist noch nicht möglich, aber ya dies wird die Ergebnisse in angemessener Art und Weise verlassen mit allen Kombination von SVF filtern und 1 und Relevanz der Ergebnisse Sortierung, die SVF-1 fördert bis der Auftrag

Für das exakte Ergebnis heraus~~POS=TRUNC

"settings": { 
     "analysis": { 
      "analyzer": { 
       "analyzer_keyword": { 
        "type": "custom", 
        "tokenizer": "keyword", 
        "filter": [ 
         "lowercase" 
        ] 
       } 
      } 
     } 
    }, 
    "mappings": { 
     "type": { 
      "properties": { 
       "name": { 
        "type": "string", 
        "analyzer": "analyzer_keyword" 
       } 
      } 
     } 
    } 

und die Abfrage ist

{ 
    "query": { 
     "bool": { 
      "must": [ 
       { 
        "query_string" : { 
         "fields": ["name"], 
         "query" : "*svf-1*", 
         "analyze_wildcard": true 
        } 
       } 
      ] 
     } 
    } 
} 

Ergebnis

{ 
    "took": 4, 
    "timed_out": false, 
    "_shards": { 
     "total": 5, 
     "successful": 5, 
     "failed": 0 
    }, 
    "hits": { 
     "total": 1, 
     "max_score": 1, 
     "hits": [ 
     { 
      "_index": "play", 
      "_type": "type", 
      "_id": "AVfXzn3oIKphDu1OoMtF", 
      "_score": 1, 
      "_source": { 
       "name": "SVF-123" 
      } 
     } 
     ] 
    } 
} 
Verwandte Themen