@ponko11

Фасетный поиск в Elasticsearch?

Добрый день. Прошу помочь с запросом на агрегацию для фасетного поиска в интернет магазине.

мапинг такой:
function createIndex() {
    return client.indices.create({
        index: 'bs_index',
        body: {
            mappings: {
                properties: {
                    all_prop: {
                        type: 'text'
                    },
                    id: {
                        type: 'keyword',
                        copy_to: 'all_prop'
                    },
                    brand: {
                        type: 'keyword',
                        copy_to: 'all_prop'
                    },
                    sale: {
                        type: 'keyword',
                        index: false
                    },
                    img: {
                        type: 'keyword',
                        index: false
                    },
                    class: {
                        type: 'keyword',
                        copy_to: 'all_prop'
                    },
                    type: {
                        type: 'keyword',
                        copy_to: 'all_prop'
                    },
                    model: {
                        type: 'keyword',
                        copy_to: 'all_prop'
                    },
                    price: {
                        type: 'keyword',
                        index: false
                    },
                    sex: {
                        type: 'keyword',
                        copy_to: 'all_prop'
                    },
                    category: {
                        type: 'keyword',
                        copy_to: 'all_prop'
                    },
                    color: {
                        type: 'keyword',
                        copy_to: 'all_prop'
                    },
                    size: {
                        type: 'keyword',
                        copy_to: 'all_prop'
                    },
                    photo: {
                        type: 'keyword',
                        index: false
                    },
                    info: {
                        type: 'keyword',
                        copy_to: 'all_prop'
                    }
                }
            }
        }
    })
}


У самого получилось составить вот такой запрос:
GET /_search
{
 "size" : 0,
 "aggs": {
    "my_agg": {
           "aggs": {
              "price": {
                   "terms": { "field": "price","size" : 100 }
               },
              "sex": {
                   "terms": { "field": "sex","size" : 100 }
               },
              "category": {
                   "terms": { "field": "category","size" : 100 }
               },
              "color": {
                   "terms": { "field": "color","size" : 100 }
               },
              "size": {
                   "terms": { "field": "size","size" : 100 }
               },
               "brand": {
                   "terms": { "field": "brand","size" : 100 }
               }
           },
           "filter": {
             "terms": { "size": ["10US"] }
           }
    }
 }
}


В ответ получаю:
{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 15,
    "successful": 15,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 268,
      "relation": "eq"
    },
    "max_score": null,
    "hits": []
  },
  "aggregations": {
    "my_agg": {
      "doc_count": 2,
      "size": {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 0,
        "buckets": [
          {
            "key": "10US",
            "doc_count": 2
          }
        ]
      },
      "color": {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 0,
        "buckets": [
          {
            "key": "Коричневый",
            "doc_count": 1
          },
          {
            "key": "Красный",
            "doc_count": 1
          }
        ]
      },
      "price": {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 0,
        "buckets": [
          {
            "key": "11290",
            "doc_count": 1
          },
          {
            "key": "4890",
            "doc_count": 1
          }
        ]
      },
      "sex": {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 0,
        "buckets": [
          {
            "key": "Мужской",
            "doc_count": 2
          }
        ]
      },
      "category": {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 0,
        "buckets": [
          {
            "key": "Кроссовки",
            "doc_count": 2
          }
        ]
      },
      "brand": {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 0,
        "buckets": [
          {
            "key": "Nike",
            "doc_count": 2
          }
        ]
      }
    }
  }
}


Всё ок, но не для поля size. То есть показывает только выбранный размер.
У меня два вопроса:
1.Как получить значения для остальных размеров которые не активны?
2.Как составить запрос если например выбран размер и цвет?
  • Вопрос задан
  • 284 просмотра
Решения вопроса 1
@ponko11 Автор вопроса
Кажется нащупал:
Первый вариант
GET /_search
{
 "size" : 0,
 "aggs": {
    "size": {
           "aggs": {
              "price": {
                   "terms": { "field": "price","size" : 100 }
               },
              "sex": {
                   "terms": { "field": "sex","size" : 100 }
               },
              "category": {
                   "terms": { "field": "category","size" : 100 }
               },
              "color": {
                   "terms": { "field": "color","size" : 100 }
               },
               "brand": {
                   "terms": { "field": "brand","size" : 100 }
               }
           },
           "filter": {
             "bool" : {
               "filter" : [
               {
                 "terms": { "size": ["10US"] }
               }
               ]
             }
           }
    },
        "color": {
           "aggs": {
              "size": {
                   "terms": { "field": "size","size" : 100 }
               }
           },
           "filter": {
             "bool" : {
               "filter" : [
               ]
             }
           }
    }
 }
}


Второй вариант
GET /_search
{
 "size" : 0,
 "aggs": {
    "inavtive": {
           "aggs": {
              "price": {
                   "terms": { "field": "price","size" : 100 }
               },
              "sex": {
                   "terms": { "field": "sex","size" : 100 }
               },
              "category": {
                   "terms": { "field": "category","size" : 100 }
               },
               "brand": {
                   "terms": { "field": "brand","size" : 100 }
               }
           },
           "filter": {
             "bool" : {
               "filter" : [
               {
                 "terms": { "size": ["10US"] }
               },
               {
                 "terms": { "color": ["Красный"] }
               }
               ]
             }
           }
     },
        "size": {
           "aggs": {
              "size": {
                   "terms": { "field": "size","size" : 100 }
               }
           },
           "filter": {
             "bool" : {
               "filter" : [
               {
                 "terms": { "color": ["Красный"] }
               }
               ]
             }
           }
         },
      "color": {
          "aggs": {
            "size": {
               "terms": { "field": "color","size" : 100 }
             }
           },
           "filter": {
             "bool" : {
               "filter" : [
               {
                 "terms": { "size": ["10US"] }
               }
               ]
             }
            }
       }
 }
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
SpectrumData Екатеринбург
от 300 000 до 400 000 ₽
LIME Москва
от 280 000 до 350 000 ₽
22 нояб. 2024, в 00:55
500 руб./за проект
21 нояб. 2024, в 23:30
300000 руб./за проект
21 нояб. 2024, в 22:21
3000 руб./в час