2015-07-14 5 views
0

У меня есть документы типа «устройство», которое я поиск по модели, используя следующий запрос (с использованием КОЛБОЙ & Elasticsearch как API):Elasticsearch - match_phrase сортировать запрос по ИНТУ

match handset 
    query = { 
     "query": { 
      "match_phrase": { 
       "model": model_name 
      } 
     }, 
     "track_scores": True, 
     "size": 1, 
     "sort": 
      [ 
       {"_score": {"order": "desc"}}, 
       {"model": {"order": "asc"}} 
      ] 
    } 
    device = es.search(body=query, doc_type='device') 

Это возвращает одно устройство с «моделью «ближайший к запрошенному (имя модели).

Пример списка устройств:

[{ "id":482, 
    "memory":"16", 
    "model":"iPhone 5s 16GB" }, 
{ "id":483, 
    "memory":"32", 
    "model":"iPhone 5s 32GB" }, 
{ "id":484, 
    "memory":"16", 
    "model":"iPhone 5c 16GB" }, 
{ "id":486, 
    "memory":"64", 
    "model":"iPhone 6 64GB" }, 
{ "id":485, 
    "memory":"32", 
    "model":"iPhone 6 32GB" }] 

Как я могу изменить его так, чтобы вернуть устройство с самой низкой памятью?

>>> query.query.match_phrase.model = 'iPhone 5s' 
>>> device = es.search(body=query, doc_type='device') 
{ "id":482, 
    "memory":"16", 
    "model":"iPhone 5s 16GB" } 


>>> query.query.match_phrase.model = 'iPhone 6' 
>>> device = es.search(body=query, doc_type='device') 
{ "id":485, 
    "memory":"32", 
    "model":"iPhone 6 32GB" } 

Любые подсказки высоко оценены.

ответ

1

Я бы изменил тип поля "memory" на "integer" в вашем сопоставлении и соответствующим образом проиндексировал данные, тогда легко получить желаемый результат.

Таким образом, с отображением, как это:

PUT /test_index 
{ 
    "mappings": { 
     "doc": { 
     "_id": { 
      "path": "id" 
     }, 
     "properties": { 
      "id": { 
       "type": "integer" 
      }, 
      "memory": { 
       "type": "integer" 
      }, 
      "model": { 
       "type": "string" 
      } 
     } 
     } 
    } 
} 

и эти документы индексируются:

POST /test_index/doc/_bulk 
{"index":{}} 
{"id":482,"memory":16,"model":"iPhone 5s 16GB"} 
{"index":{}} 
{"id":483,"memory":32,"model":"iPhone 5s 32GB"} 
{"index":{"_id":1}} 
{"id":484,"memory":16,"model":"iPhone 5c 16GB"} 
{"index":{}} 
{"id":486,"memory":64,"model":"iPhone 6 64GB"} 
{"index":{}} 
{"id":485,"memory":32,"model":"iPhone 6 32GB"} 
{"index":{}} 

Вы можете запросить так, чтобы получить самую низкую память хит на "iPhone 5s":

POST /test_index/_search 
{ 
    "query": { 
     "match": { 
     "model": { 
      "query": "iPhone 5s", 
      "operator": "and" 
     } 
     } 
    }, 
    "sort": [ 
     { 
     "memory": { 
      "order": "asc" 
     } 
     } 
    ], 
    "size": 1 
} 
... 
{ 
    "took": 2, 
    "timed_out": false, 
    "_shards": { 
     "total": 1, 
     "successful": 1, 
     "failed": 0 
    }, 
    "hits": { 
     "total": 2, 
     "max_score": null, 
     "hits": [ 
     { 
      "_index": "test_index", 
      "_type": "doc", 
      "_id": "482", 
      "_score": null, 
      "_source": { 
       "id": 482, 
       "memory": 16, 
       "model": "iPhone 5s 16GB" 
      }, 
      "sort": [ 
       16 
      ] 
     } 
     ] 
    } 
} 

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

http://sense.qbox.io/gist/8441d7379485e03a75fdbaa9ae0bf9748098be33

+0

Это работает, приветствия. Теперь, имея «Samsung S6» и «Samsung S6 Edge» в поиске «Samsung S6», я сначала получаю Edge. Любая подсказка о том, как это исправить? –

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