Как сделать агрегацию на вложенных объектах - Elasticsearch

Я довольно новичок в Elasticsearch, поэтому, пожалуйста, потерпите меня. Это часть моего документа в ES.

{
  "source": {
    "detail": {
      "attribute": {
        "Size": ["32 Gb",4],
        "Type": ["Tools",4],
        "Brand": ["Sandisk",4],
        "Color": ["Black",4],
        "Model": ["Sdcz36-032g-b35",4],
        "Manufacturer": ["Sandisk",4]
      }
    },
    "title": {
      "list": [
        "Sandisk Cruzer 32gb Usb 32 Gb Flash Drive , Black - Sdcz36-032g"
      ]
    }
  }
}

Итак, чего я хочу добиться, так это найти лучшие три или три верхних попадания объекта атрибута. Например, если я ищу "sandisk", я хочу получить три атрибута: ["Size", "Color", "Model"] или какие-либо атрибуты, основанные на агрегации лучших хитов. Итак, я сделал такой запрос

{
  "size": 0,
  "aggs": {
    "categoryList": {
      "filter": {
        "bool": {
          "filter": [
            {
              "term": {
                "title.list": "sandisk"
              }
            }
          ]
        }
      },
      "aggs": {
        "results": {
          "terms": {
            "field": "detail.attribute",
            "size": 3
          }
        }
      }
    }
  }
}

Но, похоже, не работает. Как это исправить? Любые советы будут высоко оценены.

Это _mappings, Это не полный, но я думаю, этого будет достаточно.

{
  "catalog2_0": {
    "mappings": {
      "product": {
        "dynamic": "strict",
        "dynamic_templates": [
          {
            "attributes": {
              "path_match": "detail.attribute.*",
              "mapping": {
                "type": "text"
              }
            }
          }
        ],
        "properties": {

          "detail": {
            "properties": {
              "attMaxScore": {
                "type": "scaled_float",
                "scaling_factor": 100
              },
              "attribute": {
                "dynamic": "true",
                "properties": {
                  "Brand": {
                    "type": "text"
                  },
                  "Color": {
                    "type": "text"
                  },
                  "MPN": {
                    "type": "text"
                  },
                  "Manufacturer": {
                    "type": "text"
                  },
                  "Model": {
                    "type": "text"
                  },
                  "Operating System": {
                    "type": "text"
                  },
                  "Size": {
                    "type": "text"
                  },
                  "Type": {
                    "type": "text"
                  }
                }
              },
              "description": {
                "type": "text"
              },
              "feature": {
                "type": "text"
              },
              "tag": {
                "type": "text",
                "fields": {
                  "raw": {
                    "type": "keyword"
                  }
                }
              }
            }
          },

          "title": {
            "properties": {

              "en": {
                "type": "text"
              }
            }
          }
        }
      }
    }
  }
}

2 ответа

Решение
  • Согласно документации, вы не можете сделать агрегацию на поле, которое имеет text тип данных. Они должны иметь keyword тип данных.

  • Тогда вы не можете сделать агрегацию на detail.attribute поле таким образом: detail.attribute поле не хранит никакого значения: это object тип данных - не nested один, как вы написали в вопросе, это означает, что это контейнер для другого поля, как Size, Brand и т.д. Поэтому вы должны объединиться против detail.attribute.Size поле - если это был keyword тип данных - например.

  • Другая вероятная ошибка заключается в том, что вы пытаетесь запустить term запрос на text тип данных - что такое тип данных title.list поле?. Term запрос является прерогативой для поля, которое имеет keyword тип данных, в то время как match запрос используется для запроса против text тип данных

Вот что я использовал для вложенного запроса aggs, за исключением фактических имен значений. Фактическое поле - это ключевое слово, которое, как уже упоминалось, является обязательным, является частью вложенного объекта JSON:

"STATUS_ID": {
                "type": "keyword",
                "index": "not_analyzed",
                "doc_values": true
              },

запрос

  GET index name/_search?size=200
    {
      "aggs": {
        "panels": {
          "nested": {
            "path": "nested path"
          },
          "aggs": {
            "statusCodes": {
              "terms": {
                "field": "nested path.STATUS.STATUS_ID",
                "size": 50
              }
            }
          }
        }
      }
    }

Результат

"aggregations": {
    "status": {
      "doc_count": 12108963,
      "statusCodes": {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 0,
        "buckets": [
          {
            "key": "O",
            "doc_count": 5912218
          },
          {
            "key": "C",
            "doc_count": 401586
          },
          {
            "key": "E",
            "doc_count": 135628
          },
          {
            "key": "Y",
            "doc_count": 3742
          },
          {
            "key": "N",
            "doc_count": 1012
          },
          {
            "key": "L",
            "doc_count": 719
          },
          {
            "key": "R",
            "doc_count": 243
          },
          {
            "key": "H",
            "doc_count": 86
          }
        ]
      }
    }
Другие вопросы по тегам