2015-03-25 2 views
0

Я не знаю, возможно ли это, но я пытаюсь выполнить поиск по местоположению с опцией «точный поиск». Есть несколько полей, которые получают искали, с наиболее важным из которых является «location_raw» поле:Elastic Search: Любой способ сделать слова, разделенные пробелами, в разделенном запятой списке, рассматриваемом как один термин?

"match": { 
    "location.location_raw": { 
     "type": "boolean", 
     "operator": "AND", 
     "query": "[location query]", 
     "analyzer": "standard" 
    } 
} 

location_raw поле местоположения строки с запятой между каждым местом, такими как «Садбери, Middlesex, Массачусетс »или« Лимингтон, Уорикшир, Англия ». Если кто-то ищет «Садбери, Middlesex» она будет передана в качестве

"query": "Sudbury Middlesex" 

и оба эти условия должны существовать в location_raw поле. Эта часть работает.

Проблема заключается в том, что когда поле location_raw содержит многословное местоположение, например Нью-Йорк или Сент-Джордж, они возвращаются, когда кто-то ищет «Йорк» или «Джордж». Если я сделаю точный поиск «Джордж», я не хочу получать результаты для «Святого Георгия». Есть ли способ заставить Эластику считать «Святой Георгий» одним термином в строчке «Святой Георгий, Стэмфорд, Линкольн, Англия»?

ответ

3

Вот один из способов сделать это, но вам нужно также запросить в csv или использовать terms filter.

Я использовал pattern analyzer с простым рисунком: ", ". Я создал простой индекс с одним документом:

PUT /test_index 
{ 
    "settings": { 
     "number_of_shards": 1, 
     "analysis": { 
     "analyzer": { 
      "csv": { 
       "type": "pattern", 
       "pattern": ", ", 
       "lowercase": false 
      } 
     } 
     } 
    }, 
    "mappings": { 
     "doc": { 
     "properties": { 
      "location": { 
       "type": "string", 
       "index_analyzer": "csv", 
       "search_analyzer": "standard", 
       "fields": { 
        "raw": { 
        "type": "string", 
        "index": "not_analyzed" 
        } 
       } 
      } 
     } 
     } 
    } 
} 

POST /test_index/_bulk 
{"index":{"_index":"test_index","_type":"doc","_id":1}} 
{"location":"Saint George, Stamford, Lincoln, England"} 

я могу увидеть условия, созданные с помощью простого terms aggregation:

POST /test_index/_search?search_type=count 
{ 
    "aggs": { 
     "location_terms": { 
     "terms": { 
      "field": "location" 
     } 
     } 
    } 
} 
... 
{ 
    "took": 1, 
    "timed_out": false, 
    "_shards": { 
     "total": 1, 
     "successful": 1, 
     "failed": 0 
    }, 
    "hits": { 
     "total": 1, 
     "max_score": 0, 
     "hits": [] 
    }, 
    "aggregations": { 
     "location_terms": { 
     "buckets": [ 
      { 
       "key": "England", 
       "doc_count": 1 
      }, 
      { 
       "key": "Lincoln", 
       "doc_count": 1 
      }, 
      { 
       "key": "Saint George", 
       "doc_count": 1 
      }, 
      { 
       "key": "Stamford", 
       "doc_count": 1 
      } 
     ] 
     } 
    } 
} 

И потом, если я запрашиваю с тем же синтаксисом, CSV, документ ISN «т вернулся на "Джордж, Англия":

POST /test_index/_search 
{ 
    "query": { 
     "match": { 
     "location": { 
      "type": "boolean", 
      "operator": "AND", 
      "query": "George, England", 
      "analyzer": "csv" 
     } 
     } 
    } 
} 
... 
{ 
    "took": 0, 
    "timed_out": false, 
    "_shards": { 
     "total": 1, 
     "successful": 1, 
     "failed": 0 
    }, 
    "hits": { 
     "total": 0, 
     "max_score": null, 
     "hits": [] 
    } 
} 

, но для "Сент-Джордж, Англия":

POST /test_index/_search 
{ 
    "query": { 
     "match": { 
     "location": { 
      "type": "boolean", 
      "operator": "AND", 
      "query": "Saint George, England", 
      "analyzer": "csv" 
     } 
     } 
    } 
} 
... 
{ 
    "took": 1, 
    "timed_out": false, 
    "_shards": { 
     "total": 1, 
     "successful": 1, 
     "failed": 0 
    }, 
    "hits": { 
     "total": 1, 
     "max_score": 0.2169777, 
     "hits": [ 
     { 
      "_index": "test_index", 
      "_type": "doc", 
      "_id": "1", 
      "_score": 0.2169777, 
      "_source": { 
       "location": "Saint George, Stamford, Lincoln, England" 
      } 
     } 
     ] 
    } 
} 

Этот запрос эквивалентен, и, вероятно, более производительным:

POST /test_index/_search 
{ 
    "query": { 
     "filtered": { 
     "query": { 
      "match_all": {} 
     }, 
     "filter": { 
      "terms": { 
       "location": [ 
        "Saint George", 
        "England" 
       ], 
       "execution": "and" 
      } 
     } 
     } 
    } 
} 

Вот код, который я использовал, чтобы проверить:

http://sense.qbox.io/gist/234ea93accb7b20ad8fd33e62fe92f1d450a51ab

Смежные вопросы