当前位置: 首页 > 面试题库 >

ElasticSearch-从索引中获取所有可用的过滤器(聚合)

孔永年
2023-03-14
问题内容

假设我有:

"hits": [
      {
        "_index": "products",
        "_type": "product",
        "_id": "599c2b3fc991ee0a597034fa",
        "_score": 1,
        "_source": {,
          "attributes": {
            "1": [
              "a"
            ],
            "2": [
              "b",
              "c"
            ],
            "3": [
              "d",
              "e"
            ],
            "4": [
              "f",
              "g"
            ],
            "5": [
              "h",
              "i"
            ]
          }
        }
      },
      {
        "_index": "products",
        "_type": "product",
        "_id": "599c4bb4b970c25976ced8bd",
        "_score": 1,
        "_source": {
          "attributes": {
            "1": [
              "z"
            ],
            "2": [
              "y"
            ]
          }
        }

每个产品都有属性。每个属性都有ID和一个值。我可以按属性筛选产品,但现在我要从MongoDB创建“可能的属性”列表。我想找到一种单独从ElasticSearch生成这样的列表的方法(也许只是向MongoDB查询其他数据)。

我需要的是:

{
  1: [a, z],
  2: [b, c, y],
  etc.
}

这样的聚合看起来如何?获取所有可用属性(按分组attribute.id)及其所有可能值(在所有产品中)?


问题答案:

您无法在一个查询中做到这一点,但在两个查询中却很简单:

检索属性列表

您可以使用映射来获取文档中的所有字段:

curl -XGET "http://localhost:9200/your_index/your_type/_mapping"

检索他们的价值

然后,您可以使用多个术语聚合来获取字段的所有值:

curl -XGET "http://localhost:9200/your_index/your_type/_search" -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "field1Values": {
      "terms": {
        "field": "field1",
        "size": 20
      }
    },
    "field2Values": {
      "terms": {
        "field": "field2",
        "size": 20
      }
    },
    "field3Values": {
      "terms": {
        "field": "field3",
        "size": 20
      }
    },
    ...
  }
}'

这将检索每个字段的前20个最常出现的值。

限制为20个值是防止产生巨大响应的限制(例如,如果您有数十亿个具有唯一字段的文档)。您可以修改术语聚合的“大小”参数以增加它。根据您的要求,我想选择一个比每个字段获取的不同值的数量的大致估计大10倍的方法可以解决问题。

如何处理价值的巨大基数

您还可以使用基数聚合进行中间查询,以获取此实际值,然后将其用作术语聚合的大小。请注意,基数不是一个大数的估计值,因此您可能想使用cardinality * 2

curl -XGET "http://localhost:9200/your_index/your_type/_search" -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "field1Cardinality": {
      "cardinality": {
        "field": "field1"
      }
    },
    "field2Cardinality": {
      "cardinality": {
        "field": "field2"
      }
    },
    "field3Cardinality": {
      "cardinality": {
        "field": "field3"
      }
    },
    ...
  }
}'

如何处理价值的巨大基数

如果没有太多不同的属性,则前一种方法适用。如果有的话,您应该更改文档的存储方式,以防止Mapping爆炸,

像这样存储它们:

{
    "attributes":[
        {
            "name":"1",
            "value":[
                "a"
            ]
        },
        {
            "name":"2",
            "value":[
                "b",
                "c"
            ]
        },
        {
            "name":"3",
            "value":[
                "d",
                "e"
            ]
        },
        {
            "name":"4",
            "value":[
                "f",
                "g"
            ]
        },
        {
            "name":"5",
            "value":[
                "h",
                "i"
            ]
        }
    ]
}

将解决此问题,您将能够在“名称”上使用术语汇总,然后在“值”上使用子术语汇总来获得所需的内容:

curl -XGET "http://localhost:9200/your_index/your_type/_search" -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "attributes": {
      "terms": {
        "field": "attributes.name",
        "size": 1000
      },
      "aggs": {
        "values": {
          "terms": {
            "field": "attributes.value",
            "size": 100
          }
        }
      }
    }
  }
}'

它要求对属性使用嵌套映射。



 类似资料:
  • 问题内容: 我有一个包含嵌套对象的文档,如下所示: 现在,我需要按书名(不是book_title)和年份(比如2014)来过滤书籍。我需要的输出将是: 当我使用嵌套过滤器时,即使它们不匹配,我也会得到所有嵌套对象。如何仅获取匹配的嵌套对象? 问题答案: 您需要使用以下嵌套功能。 在输出中,您将确切地获得期望的结果,即字段和嵌套数组中的匹配书。

  • 我想要一个Elasticsearch索引,它只存储功能的“名称”。我希望能够发出语音查询,也可以单独键入前置式查询。我想我可以用两个分析器和两个过滤器创建一个索引;每个分析仪可以使用其中一个过滤器。但我似乎无法做到这一点。 以下是我尝试使用的索引设置json: 当我尝试使用这些设置创建索引时: 我得到一个HTTP 400,说 别误会,我完全明白这句话的意思。我看了又看,寻找一个错误的逗号或引号,但

  • 问题内容: 我想从Elasticsearch集群中的完全匹配查询中获取所有结果。我不在乎结果是否是最新的,我不在乎订单,我只想稳定地浏览所有结果,然后从头开始。滚动和扫描最适合此操作,似乎不需要我拍摄快照就很受欢迎。我将要处理数以千万计的文档。 问题答案: 某种程度上与Elasticsearch查询重复,以返回所有记录。但是我们可以添加更多细节来解决开销问题。(即,“拍摄不需要的快照似乎有点受欢迎

  • 我想知道推荐的方法是什么来过滤掉从存储和索引发送到Elasticsearch的一些字段? 我想过滤我们的一些字段,使其不在Elasticsearch中被索引。您可能会问,为什么从一开始就将它们发送到Elasticsearch。不幸的是,它是通过另一个不接受任何过滤机制的应用程序发送的。因此,应在索引时解决过滤问题。以下是我们所做的,但我不确定这些步骤会产生什么后果: 1-禁用ES模板中的动态映射(

  • 问题内容: 我有集群,我想知道其中的所有索引和类型的名称。我用Sense。 问题答案: 将为您提供所有索引。 将为您提供这些索引中的文档类型及其映射。

  • 问题内容: 这是我的模样 我试图在线查找有关如何从请求中获取价值的信息。 我什么也没找到,所以我尝试枚举,并且一无所知,但是没有任何标题。 问题 如何获得来自请求的所有标头? 问题答案: 类型转换成(仅当是一个 )。 然后可以使用和方法。 像这样: