2017-02-01 3 views
2

Я работаю над проектом, касающимся рецептов приготовления. Я установил Elasticsearch 1.5.2, и я добавил много продуктов, таких как овощи или мясо во многих индексах супермаркетов. Все было хорошо, пока я не начал агрегирование запросов. Например: чтобы приготовить картофельный пюре, мне нужен картофель, фасоль, нут, брокколи, молоко, перец, соль. У меня есть все эти продукты. Мне нужно сделать один запрос, чтобы искать самые дешевые из этих продуктов во всех индексах. Я пробовал много запросов, но не нашел, что мне нужно.Запросы на сборку Elasticsearch

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

POST /_search 
    { 
     "query": { 
      "query_string": { 
       "query": "pommes de terre", 
       "fields": [ 
        "titre" 
       ] 
      } 
     }, 
     "sort" : [ 
      {"prix en €/kg" : {"order" : "asc"}} 
     ] 
    } 

    POST /_search 
    { 
     "query": { 
      "query_string": { 
       "query": "haricots", 
       "fields": [ 
        "titre" 
       ] 
      } 
     }, 
     "sort" : [ 
      {"prix en €/kg" : {"order" : "asc"}} 
     ] 
    } 

    POST /_search 
    { 
     "query": { 
      "query_string": { 
       "query": "pois chiche", 
       "fields": [ 
        "titre" 
       ] 
      } 
     }, 
     "sort" : [ 
      {"prix en €/kg" : {"order" : "asc"}} 
     ] 
    } 

    POST /_search 
    { 
     "query": { 
      "query_string": { 
       "query": "brocoli", 
       "fields": [ 
        "titre" 
       ] 
      } 
     }, 
     "sort" : [ 
      {"prix en €/kg" : {"order" : "asc"}} 
     ] 
    } 

    POST /_search 
    { 
     "query": { 
      "query_string": { 
       "query": "lait", 
       "fields": [ 
        "tags" 
       ] 
      } 
     }, 
     "sort" : [ 
      {"prix en €/L" : {"order" : "asc"}} 
     ] 
    } 

    POST /_search 
    { 
     "query": { 
      "query_string": { 
       "query": "poivre", 
       "fields": [ 
        "tags" 
       ] 
      } 
     }, 
     "sort" : [ 
      {"prix en €/kg" : {"order" : "asc"}} 
     ] 
    } 

    POST /_search 
    { 
     "query": { 
      "query_string": { 
       "query": "sel", 
       "fields": [ 
        "tags" 
       ] 
      } 
     }, 
     "sort" : [ 
      {"prix en €/kg" : {"order" : "asc"}} 
     ] 
    } 

Я хочу иметь только один запрос для выборки результатов всех этих запросов, и я хочу только самый дешевый но не все списки.

ответ

0

Вы можете определить filter aggregation для каждого продукта в запросе

{ 
    "aggs" : { 
     "sel" : { 
      "filter" : { 
       "query_string": { 
        "query": "sel", 
        "fields": [ 
         "titre" 
        ] 
       } 
      } 
     }, 
     "haricots" : { 
      "filter" : { 
       "query_string": { 
        "query": "haricots", 
        "fields": [ 
         "titre" 
        ] 
       } 
      } 
     } 
    } 
} 

Обратите внимание, что на ES < 2, вы probably will have to wrap your filter в query объекта:

{ 
    "aggs" : { 
     "sel" : { 
      "filter" : { 
       "query": { 
        "query_string": { 
         "query": "sel", 
         "fields": [ 
          "titre" 
         ] 
        } 
       } 
      } 
     }, 
     "haricots" : { 
      "filter" : { 
       "query": { 
        "query_string": { 
         "query": "haricots", 
         "fields": [ 
          "titre" 
         ] 
        } 
       } 
      } 
     } 
    } 
} 

Каждая агрегация построить ведро, соответствующие Вашей фильтры. Затем вы добавили top hits sub aggregation к каждому из этих ковшей, чтобы получить самую низкую цену. Например, с Сель ведро:

{ 
    "aggs" : { 
     "sel" : { 
      "filter" : { 
       "query_string": { 
        "query": "sel", 
        "fields": [ 
         "titre" 
        ] 
       } 
      }, 
      "aggs" : { 
       "minprice": { 
        "top_hits": { 
         "sort": [ 
          { 
           "prix en €/kg": { 
            "order": "asc" 
           } 
          } 
         ], 
         "size" : 1 
        } 
       } 
      } 
     } 
    } 
} 

и более глубоко, например, с Сель, Brocoli и фасоль

{ 
    "aggs" : { 
     "sel" : { 
      "filter" : { 
       "query_string": { 
        "query": "sel", 
        "fields": [ 
         "titre" 
        ] 
       } 
      }, 
      "aggs" : { 
       "minprice": { 
        "top_hits": { 
         "sort": [ 
          { 
           "prix en €/kg": { 
            "order": "asc" 
           } 
          } 
         ], 
         "size" : 1 
        } 
       } 
      } 
     }, 
     "haricots" : { 
      "filter" : { 
       "query_string": { 
        "query": "haricots", 
        "fields": [ 
         "titre" 
        ] 
       } 
      }, 
      "aggs" : { 
       "minprice": { 
        "top_hits": { 
         "sort": [ 
          { 
           "prix en €/kg": { 
            "order": "asc" 
           } 
          } 
         ], 
         "size" : 1 
        } 
       } 
      } 
     }, 
     "brocoli" : { 
      "filter" : { 
       "query_string": { 
        "query": "brocoli", 
        "fields": [ 
         "titre" 
        ] 
       } 
      }, 
      "aggs" : { 
       "minprice": { 
        "top_hits": { 
         "sort": [ 
          { 
           "prix en €/kg": { 
            "order": "asc" 
           } 
          } 
         ], 
         "size" : 1 
        } 
       } 
      } 
     } 
    } 
} 

Ваши результаты будут выглядеть как

{ 
    "aggregations" : { 
     "sel" : { 
      "doc_count" : 2, 
      "minprice" : { 
       "hits" : { 
        "total" : 2, 
        "max_score" : null, 
        "hits" : [ 
         { 
          "_index" : "test", 
          "_type" : "product", 
          "_id" : "1", 
          "_score" : null, 
          "_source" : { 
           "id" : 1, 
           "titre" : "sel 1", 
           "prix en €/kg" : 1 
          }, 
          "sort" : [ 
           1.0 
          ] 
         } 
        ] 
       } 
      } 
     }, 
     "haricots" : { 
      "doc_count" : 1, 
      "minprice" : { 
       "hits" : { 
        "total" : 1, 
        "max_score" : null, 
        "hits" : [ 
         { 
          "_index" : "test", 
          "_type" : "product", 
          "_id" : "3", 
          "_score" : null, 
          "_source" : { 
           "id" : 3, 
           "titre" : "haricots", 
           "prix en €/kg" : 3 
          }, 
          "sort" : [ 
           3.0 
          ] 
         } 
        ] 
       } 
      } 
     } 
    } 
} 
+0

Спасибо. Но у меня есть эта ошибка: «SearchPhaseExecutionException [Не удалось выполнить фазу [запрос], все осколки не пройдены; shardFailures {[tZ-AvbvUQAaemOy2BSk_2Q] [testindex] [0]: SearchParseException [[testindex] [0]: from [- 1], size [-1]: Parse Failure [Failed to parse source .......] " –

+0

Возможно, проблема транспонирования: убедитесь, что имена полей и индексов действительно то, что у вас есть на вашем сервере. – nikoshr

+0

Должен ли я добавить, например, «sel» во все мои индексы, чтобы это сработало? { "Сель": { "фильтр": { "QUERY_STRING": { "запрос": "Сель", "полей": [ "титр" ] } }, " Aggs»: { "minprice": { "top_hits": { "сорт": [ { "Приза ан €/кг": { "порядок": "по возрастанию" } } ], «размер»: 1 } } } } } –

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