2015-11-15 3 views
1

Я хочу предложить грандиозный поиск одежды на некоторых платформах. Поскольку у меня уже есть функция поиска на основе Elasticsearch (простой запрос, только имя продукта), было бы неплохо также реализовать фасетный поиск с помощью ES.Elasticsearch правильные скопления для фасциального поиска

Это должно быть сделано с помощью агрегатов, поскольку гранулы устарели, а также могут иметь вложенные агрегаты.

Однако я не могу обернуть мою голову вокруг миллионов агрегатов и какие из них являются для меня - есть terms, filter, filters, nested, children и так далее. И все они кажутся подходящими.

Что я хочу достичь может показаться довольно простым: у меня разные грани (бренд, состояние, цвет), каждый из которых имеет разные значения. Для некоторых аспектов (брендов) пользователь может выбрать только одно значение. Для других (цвет) пользователю разрешено выбирать до 3 (поскольку некоторые одежды имеют более одного цвета).


Я начал с многогранных терминов facet. Теперь следующим естественным шагом будет преобразование этого в агрегирование терминов (причины выше), но многополевые поля не поддерживаются в терминах агрегирования.

Я как-то пропустил какой-то простой, но важный момент, касающийся того, как действовать параллельно с параллельным многоуровневым балансированием. Говоря с точки зрения пользовательского интерфейса пользователь должен иметь возможность выбрать что-то вроде:

  • Brands (10)
    • А (7)
    • В (3) [X]
  • цвета (5)
    • Синий (3) [X]
    • красного (2) [X]

чтение: выберите А (7), голубой (3) и красного (2)

ответ

1

Я создал базовое отображение, как это

POST your_index/your_type/_mapping 
{ 
    "your_type": { 
    "properties": { 
     "product": { 
     "type": "string" 
     }, 
     "brand": { 
     "type": "string" 
     }, 
     "color": { 
     "type": "string" 
     } 
    } 
    } 
} 

Я вставил некоторые документы, как это

PUT your_index/your_type/111 
{ 
    "product" : "jeans" ,"brand" : "lee", "color" : "blue" 
} 

PUT your_index/your_type/1111 
{ 
    "product" : "shoes" ,"brand" : "levi", "color" : "black" 
} 

And so on 

Простой запрос агрегации, как этот

GET your_index/_search 
{ 
    "size": 0, 
    "aggs": { 
    "prod_agg": { 
     "terms": { 
     "field": "product" 
     }, 
     "aggs": { 
     "brand_agg": { 
      "terms": { 
      "field": "brand" 
      }, 
      "aggs": { 
      "color_agg": { 
       "terms": { 
       "field": "color" 
       } 
      } 
      } 
     } 
     } 
    } 
    } 
} 

будет Retrun

"aggregations": { 
     "prod_agg": { 
     "doc_count_error_upper_bound": 0, 
     "sum_other_doc_count": 0, 
     "buckets": [ 
      { 
       "key": "shoes", 
       "doc_count": 4, 
       "brand_agg": { 
        "doc_count_error_upper_bound": 0, 
        "sum_other_doc_count": 0, 
        "buckets": [ 
        { 
         "key": "nike", 
         "doc_count": 3, 
         "color_agg": { 
          "doc_count_error_upper_bound": 0, 
          "sum_other_doc_count": 0, 
          "buckets": [ 
           { 
           "key": "blue", 
           "doc_count": 2 
           }, 
           { 
           "key": "black", 
           "doc_count": 1 
           } 
          ] 
         } 
        }, 
        { 
         "key": "levi", 
         "doc_count": 1, 
         "color_agg": { 
          "doc_count_error_upper_bound": 0, 
          "sum_other_doc_count": 0, 
          "buckets": [ 
           { 
           "key": "black", 
           "doc_count": 1 
           } 
          ] 
         } 
        } 
        ] 
       } 
      }, 
      { 
       "key": "jeans", 
       "doc_count": 3, 
       "brand_agg": { 
        "doc_count_error_upper_bound": 0, 
        "sum_other_doc_count": 0, 
        "buckets": [ 
        { 
         "key": "lee", 
         "doc_count": 2, 
         "color_agg": { 
          "doc_count_error_upper_bound": 0, 
          "sum_other_doc_count": 0, 
          "buckets": [ 
           { 
           "key": "black", 
           "doc_count": 1 
           }, 
           { 
           "key": "blue", 
           "doc_count": 1 
           } 
          ] 
         } 
        }, 
        { 
         "key": "levi", 
         "doc_count": 1, 
         "color_agg": { 
          "doc_count_error_upper_bound": 0, 
          "sum_other_doc_count": 0, 
          "buckets": [ 
           { 
           "key": "black", 
           "doc_count": 1 
           } 
          ] 
         } 
        } 
        ] 
       } 
      } 
     ] 
     } 
    } 

Это может быть использовано для заполнения UI критериям поиска.

Тогда Если пользователь хочет найти обувь, вы можете запросить

GET your_index/_search 
{ 
    "size": 0, 
    "query": { 
    "match": { 
     "product": "shoes" 
    } 
    }, 
    "aggs": { 
    "brand_agg": { 
     "terms": { 
     "field": "brand" 
     }, 
     "aggs": { 
     "color_agg": { 
      "terms": { 
      "field": "color" 
      } 
     } 
     } 
    } 
    } 
} 

который даст вам

"aggregations": { 
     "brand_agg": { 
     "doc_count_error_upper_bound": 0, 
     "sum_other_doc_count": 0, 
     "buckets": [ 
      { 
       "key": "nike", 
       "doc_count": 3, 
       "color_agg": { 
        "doc_count_error_upper_bound": 0, 
        "sum_other_doc_count": 0, 
        "buckets": [ 
        { 
         "key": "blue", 
         "doc_count": 2 
        }, 
        { 
         "key": "black", 
         "doc_count": 1 
        } 
        ] 
       } 
      }, 
      { 
       "key": "levi", 
       "doc_count": 1, 
       "color_agg": { 
        "doc_count_error_upper_bound": 0, 
        "sum_other_doc_count": 0, 
        "buckets": [ 
        { 
         "key": "black", 
         "doc_count": 1 
        } 
        ] 
       } 
      } 
     ] 
     } 
    } 

или вы могли бы иметь их как отдельные ведра с запросом как

GET your_index/_search 
{ 
    "size": 0, 
    "query": { 
    "match": { 
     "product": "shoes" 
    } 
    }, 
    "aggs": { 
    "brand_agg": { 
     "terms": { 
     "field": "brand" 
     } 
    }, 
    "color_agg" : { 
     "terms": { 
     "field": "color" 
     } 
    } 
    } 
} 

, который даст вам

"aggregations": { 
     "color_agg": { 
     "doc_count_error_upper_bound": 0, 
     "sum_other_doc_count": 0, 
     "buckets": [ 
      { 
       "key": "black", 
       "doc_count": 2 
      }, 
      { 
       "key": "blue", 
       "doc_count": 2 
      } 
     ] 
     }, 
     "brand_agg": { 
     "doc_count_error_upper_bound": 0, 
     "sum_other_doc_count": 0, 
     "buckets": [ 
      { 
       "key": "nike", 
       "doc_count": 3 
      }, 
      { 
       "key": "levi", 
       "doc_count": 1 
      } 
     ] 
     } 
    } 

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

Соответствует ли это вашим требованиям?

+0

Спасибо за ваше время. Я бы сказал, что самая последняя часть с отдельными ведрами представляет собой список образцов в конце моего вопроса. То, что я до сих пор не совсем понимаю, - это то, как я могу получить пользовательский ввод (например, выбрать цвета «синий» и «красный»), а также предоставить ведра для других полей. Могу ли я это переусердствовать - это всего лишь комбинация поискового запроса + агрегация? – Anton

+0

Из вопроса, который вы опубликовали, я чувствую, что запрос + агрегация должна удовлетворять большинству ваших требований. – ChintanShah25

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