2014-10-21 4 views
11

Ich versuche eine Autocomplete-Funktion mit angularjs und elasticsearch für ein bestimmtes Feld zu erstellen, zum Beispiel countryname. Es kann einfache Namen wie "Frankreich", "Spanien" oder "zusammengesetzte Namen" wie "Sierra Leone" enthalten.elasticsearch mapping tokenizer Schlüsselwort, um Token zu vermeiden und die Verwendung von Wildcard zu ermöglichen

In der Abbildung dieses Feld not_analyzed zu verhindern elastische zu tokenize „komponierten Namen“

"COUNTRYNAME" : {"type" : "string", "store" : "yes","index": "not_analyzed" } 

ich abfragen Elasticsearch müssen, ist:

  • filtern das Dokument mit so etwas wie „COUNTRY: Wert "where Wert kann Platzhalter
  • enthalten und eine Aggregation für den vom Filter zurückgegebenen Ländernamen vornehmen (ich mache Aggregation, um nur eindeutige Daten zu erhalten, die Zählung ist für mich nutzlos, vielleicht die re eine bessere Lösung) ist

Ich kann nicht Wildcard mit dem „not_analyzed“ Feld verwenden:

diese meine Frage ist aber Platzhalter in „Wert“ Variable funktioniert nicht und es ist Fall empfindlich:

Die Wildcard allein ihre Arbeit:

curl -XGET 'local_host:9200/botanic/specimens/_search?size=0' -d '{ 
    "fields": [ 
    "COUNTRYNAME" 
    ], 
    "query": { 
    "query_string": { 
     "query": "COUNTRYNAME:*" 
    } 
    }, 
    "aggs": { 
    "general": { 
     "terms": { 
     "field": "COUNTRYNAME", 
     "size": 0 
     } 
    } 
    } 
}' 

aber das funktioniert nicht (Franken *):

curl -XGET 'local_host:9200/botanic/specimens/_search?size=0' -d '{ 
    "fields": [ 
    "COUNTRYNAME" 
    ], 
    "query": { 
    "query_string": { 
     "query": "COUNTRYNAME:Franc*" 
    } 
    }, 
    "aggs": { 
    "general": { 
     "terms": { 
     "field": "COUNTRYNAME", 
     "size": 0 
     } 
    } 
    } 
}' 

Ich habe auch versucht mit bool must query aber nicht mit diesem not_analyzed Feld und Wildcard arbeiten:

curl -XGET 'local_host:9200/botanic/specimens/_search?size=0' -d '{ 
    "fields": [ 
    "COUNTRYNAME" 
    ], 
    "query": { 
    "bool": { 
     "must": [ 
     { 
      "match": { 
      "COUNTRYNAME": "Franc*" 
      } 
     } 
     ] 
    } 
    }, 
    "aggs": { 
    "general": { 
     "terms": { 
     "field": "COUNTRYNAME", 
     "size": 0 
     } 
    } 
    } 
}' 

Was mir persönlich fehlt oder falsch? sollte ich das Feld analyzed im Mapping verlassen und einen anderen Analysator verwenden, der zusammengesetzten Namen nicht in Token spaltet?

Antwort

21

Ich habe eine funktionierende Lösung gefunden: den Tokenizer "keyword". einen eigenen Analysator erstellen und sie in der Abbildung für das Feld verwenden i ohne durch den Raum geteilt behalten will:

curl -XPUT 'localhost:9200/botanic/' -d '{ 
"settings":{ 
    "index":{ 
     "analysis":{ 
      "analyzer":{ 
       "keylower":{ 
       "tokenizer":"keyword", 
       "filter":"lowercase" 
       } 
      } 
     } 
    } 
    }, 
    "mappings":{ 
     "specimens" : { 
      "_all" : {"enabled" : true}, 
      "_index" : {"enabled" : true}, 
      "_id" : {"index": "not_analyzed", "store" : false}, 
      "properties" : { 
       "_id" : {"type" : "string", "store" : "no","index": "not_analyzed" } , 
      ... 
       "LOCATIONID" : {"type" : "string", "store" : "yes","index": "not_analyzed" } , 
       "AVERAGEALTITUDEROUNDED" : {"type" : "string", "store" : "yes","index": "analyzed" } , 
       "CONTINENT" : {"type" : "string","analyzer":"keylower" } , 
       "COUNTRYNAME" : {"type" : "string","analyzer":"keylower" } ,     
       "COUNTRYCODE" : {"type" : "string", "store" : "yes","index": "analyzed" } , 
       "COUNTY" : {"type" : "string","analyzer":"keylower" } , 
       "LOCALITY" : {"type" : "string","analyzer":"keylower" }     
      } 
     } 
    } 
}' 

, so kann ich Wildcard in Abfrage auf dem Feld COUNTRY verwenden, die nicht gesplittet wird:

curl -XGET 'localhost:9200/botanic/specimens/_search?size=10' -d '{ 
"fields" : ["COUNTRYNAME"],  
"query": {"query_string" : { 
        "query": "COUNTRYNAME:bol*" 
}}, 
"aggs" : { 
    "general" : { 
     "terms" : { 
      "field" : "COUNTRYNAME", "size":0 
     } 
    } 
}}' 

das Ergebnis:

{ 
    "took" : 14, 
    "timed_out" : false, 
    "_shards" : { 
     "total" : 5, 
     "successful" : 5, 
     "failed" : 0 
    }, 
    "hits" : { 
     "total" : 45, 
     "max_score" : 1.0, 
     "hits" : [{ 
       "_index" : "botanic", 
       "_type" : "specimens", 
       "_id" : "91E7B53B61DF4E76BF70C780315A5DFD", 
       "_score" : 1.0, 
       "fields" : { 
        "COUNTRYNAME" : ["Bolivia, Plurinational State of"] 
       } 
      }, { 
       "_index" : "botanic", 
       "_type" : "specimens", 
       "_id" : "7D811B5D08FF4F17BA174A3D294B5986", 
       "_score" : 1.0, 
       "fields" : { 
        "COUNTRYNAME" : ["Bolivia, Plurinational State of"] 
       } 
      } ... 
     ] 
    }, 
    "aggregations" : { 
     "general" : { 
      "buckets" : [{ 
        "key" : "bolivia, plurinational state of", 
        "doc_count" : 45 
       } 
      ] 
     } 
    } 
} 
+0

Dank @Anainlb für Lösung. Das hat für meinen ähnlichen Fall funktioniert. – hemu

+0

froh, dass es hilft. Fühlen Sie sich frei, jede Verbesserung zu teilen;) – AlainIb

+0

@AlainIb Es war meine Schuld, wie Sie sehen können, das 'ng-Modell' sollte innerhalb '' Tag sein, aber es war innerhalb '

Verwandte Themen