用于获取过滤器选项的ElasticSearch项聚合

fquxozlt  于 2022-12-03  发布在  ElasticSearch
关注(0)|答案(1)|浏览(175)

我试图实现产品搜索,并希望得到搜索结果与过滤器过滤。我已经设法得到过滤器关键字参考,但也希望这些关键字的值
我产品正文是

{
      ...product,
       "attributes": [
            {
              "name": "Color",
              "value": "Aqua Blue"
            },
            {
              "name": "Gender",
              "value": "Female"
            },
            {
              "name": "Occasion",
              "value": "Active Wear"
            },
            {
              "name": "Size",
              "value": "0"
            }
          ],
 }

和im中使用this查询

GET product/_search
{
  "aggs": {
    "filters": {
      "terms": {
        "field": "attributes.name"
      
      },
      "aggs": {
        "values": {
          "terms": {
            "field": "attributes.value",
            "size": 10
          }
        }
      }
    }
    
  }
}

不知道为什么,但我得到每个键的所有值

"aggregations": {
    "filters": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "Color",
          "doc_count": 3,
          "values": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "Active Wear",
                "doc_count": 3
              },
              {
                "key": "Aqua Blue",
                "doc_count": 3
              },
              {
                "key": "Female",
                "doc_count": 3
              },
              {
                "key": "0",
                "doc_count": 2
              },
              {
                "key": "10XL",
                "doc_count": 1
              }
            ]
          }
        },
        {
          "key": "Gender",
          "doc_count": 3,
          "values": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "Active Wear",
                "doc_count": 3
              },
              {
                "key": "Aqua Blue",
                "doc_count": 3
              },
              {
                "key": "Female",
                "doc_count": 3
              },
              {
                "key": "0",
                "doc_count": 2
              },
              {
                "key": "10XL",
                "doc_count": 1
              }
            ]
          }
        },
        {
          "key": "Occasion",
          "doc_count": 3,
          "values": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "Active Wear",
                "doc_count": 3
              },
              {
                "key": "Aqua Blue",
                "doc_count": 3
              },
              {
                "key": "Female",
                "doc_count": 3
              },
              {
                "key": "0",
                "doc_count": 2
              },
              {
                "key": "10XL",
                "doc_count": 1
              }
            ]
          }
        },
        {
          "key": "Size",
          "doc_count": 3,
          "values": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "Active Wear",
                "doc_count": 3
              },
              {
                "key": "Aqua Blue",
                "doc_count": 3
              },
              {
                "key": "Female",
                "doc_count": 3
              },
              {
                "key": "0",
                "doc_count": 2
              },
              {
                "key": "10XL",
                "doc_count": 1
              }
            ]
          }
        }
      ]
    }

另外,我不想手动指定所有键显式颜色,大小以获得各自的值。谢谢:)

guz6ccqo

guz6ccqo1#

为了保持简单,必须使用单个字段来存储属性:
"gender":"Male"
我假设你有很多属性,所以你创建了一个数组,为了处理这个问题,你必须使用“嵌套”字段类型。
嵌套类型保留每个嵌套文档属性之间的关系。如果不使用嵌套,则会看到所有属性和值都混合在一起,并且如果不手动添加筛选器,则无法按属性进行聚合。
你可以在这里读到我写的一篇文章:
https://opster.com/guides/elasticsearch/data-architecture/elasticsearch-nested-field-object-field/
Map:

PUT test_product_nested
{
  "mappings": {
    "properties": {
      "attributes": {
        "type": "nested",
        "properties": {
          "name": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "value": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      },
      "title": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      }
    }
  }
}

此查询将仅显示XL大小的红色产品,并按属性进行汇总。
如果要使用OR而不是AND,则必须使用“should”子句而不是“filter”子句。
查询

POST test_product_nested/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "nested": {
            "path": "attributes",
            "query": {
              "bool": {
                "filter": [
                  {
                    "term": {
                      "attributes.name.keyword": "Color"
                    }
                  },
                  {
                    "term": {
                      "attributes.value.keyword": "Red"
                    }
                  }
                ]
              }
            }
          }
        },
        {
          "nested": {
            "path": "attributes",
            "query": {
              "bool": {
                "filter": [
                  {
                    "term": {
                      "attributes.name.keyword": "Size"
                    }
                  },
                  {
                    "term": {
                      "attributes.value.keyword": "XL"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  },
  "aggs": {
    "attributes": {
      "nested": {
        "path": "attributes"
      },
      "aggs": {
        "name": {
          "terms": {
            "field": "attributes.name.keyword"
          },
          "aggs": {
            "values": {
              "terms": {
                "field": "attributes.value.keyword",
                "size": 10
              }
            }
          }
        }
      }
    }
  }
}

结果

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0,
    "hits": [
      {
        "_index": "test_product_nested",
        "_id": "aJRayoQBtNG1OrZoEOQi",
        "_score": 0,
        "_source": {
          "title": "Product 1",
          "attributes": [
            {
              "name": "Color",
              "value": "Red"
            },
            {
              "name": "Gender",
              "value": "Female"
            },
            {
              "name": "Occasion",
              "value": "Active Wear"
            },
            {
              "name": "Size",
              "value": "XL"
            }
          ]
        }
      }
    ]
  },
  "aggregations": {
    "attributes": {
      "doc_count": 4,
      "name": {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 0,
        "buckets": [
          {
            "key": "Color",
            "doc_count": 1,
            "values": {
              "doc_count_error_upper_bound": 0,
              "sum_other_doc_count": 0,
              "buckets": [
                {
                  "key": "Red",
                  "doc_count": 1
                }
              ]
            }
          },
          {
            "key": "Gender",
            "doc_count": 1,
            "values": {
              "doc_count_error_upper_bound": 0,
              "sum_other_doc_count": 0,
              "buckets": [
                {
                  "key": "Female",
                  "doc_count": 1
                }
              ]
            }
          },
          {
            "key": "Occasion",
            "doc_count": 1,
            "values": {
              "doc_count_error_upper_bound": 0,
              "sum_other_doc_count": 0,
              "buckets": [
                {
                  "key": "Active Wear",
                  "doc_count": 1
                }
              ]
            }
          },
          {
            "key": "Size",
            "doc_count": 1,
            "values": {
              "doc_count_error_upper_bound": 0,
              "sum_other_doc_count": 0,
              "buckets": [
                {
                  "key": "XL",
                  "doc_count": 1
                }
              ]
            }
          }
        ]
      }
    }
  }
}

相关问题