【问题标题】:Difference of two query results in ElasticsearchElasticsearch 中两个查询结果的差异
【发布时间】:2018-04-12 21:09:15
【问题描述】:

假设我们有电子商务商店数据的索引,我们想要获得 2 家商店中存在的产品列表的差异。

关于索引内容的信息:存储在每个文档中的示例数据如下所示:

{
   "product_name": "sample 1",
   "store_slug": "store 1",
   "sales_count": 42,
   "date": "2018-04-04"
}

以下是查询,这些查询分别获取了我在 2 家商店中的所有产品,

Data for store 1

curl -XGET 'localhost:9200/store/_search?pretty' -H 'Content-Type: application/json' -d'
   {
       "_source": ["product_name"],
       "query": {
           "constant_score" : {
               "filter" : {
                    "bool" : {
                       "must" : [
                           { "term" : { "store_slug" : "store_1"}}]}}}}}'

Data for store 2

curl -XGET 'localhost:9200/store/_search?pretty' -H 'Content-Type: application/json' -d'
   {
       "_source": ["product_name"],
       "query": {
           "constant_score" : {
               "filter" : {
                    "bool" : {
                       "must" : [
                           { "term" : { "store_slug" : "store_2"}}]}}}}}'

是否有可能使用弹性搜索查询来获得两种结果的差异(不使用某些脚本/其他语言)?

例如上述操作:假设“商店 1”正在销售产品 [“产品 1”、“产品 2”],而“商店 2”正在销售产品 [“产品 1”、“产品 3”],因此预期输出的差异为“商店 1”和“商店 2”的产品是“产品 2”。

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    为什么不在一个查询中做呢?

    在商店 1 中但不在商店 2 中的产品:

    curl -XGET 'localhost:9200/store/_search?pretty' -H 'Content-Type: application/json' -d '{
      "_source": [
        "product_name"
      ],
      "query": {
        "constant_score": {
          "filter": {
            "bool": {
              "filter": [
                {
                  "term": {
                    "store_slug": "store_1"
                  }
                }
              ],
              "must_not": [
                {
                  "term": {
                    "store_slug": "store_2"
                  }
                }
              ]
            }
          }
        }
      }
    }'
    

    你也可以轻松地做相反的事情。

    更新

    阅读您的更新后,我认为解决此问题的最佳方法是使用 terms 聚合,首先按产品,然后按商店,并且只选择只有一个存储桶的产品(使用管道聚合)

    curl -XGET 'localhost:9200/store/_search?pretty' -H 'Content-Type: application/json' -d '{
    {
      "size": 0,
      "aggs": {
        "products": {
          "terms": {
            "field": "product_name"
          },
          "aggs": {
            "stores": {
              "terms": {
                "field": "store_slug"
              }
            },
            "min_bucket_selector": {
              "bucket_selector": {
                "buckets_path": {
                  "count": "stores._bucket_count"
                },
                "script": {
                  "source": "params.count == 1"
                }
              }
            }
          }
        }
      }
    }'
    

    【讨论】:

    • Val, Above 不会有差异,例如假设商店 1 有产品“a,b,c”,商店 2 有产品“a,b,d”。 “store1 - store 2”的预期输出应该是“c”,“store 2 - store 1”应该是“d”
    • store_slug 是一个 store slugs 数组?即您只有一个产品文档,并且可以在多个商店(通过 slug)中使用,或者您每个商店都有一个产品文档?
    • store_slug 是单值字段,因此索引中的每个文档都是给定商店的产品的销售信息。所以整个数据结构(单个文档)看起来像:“{'store_slug': 'abc', 'product_name': 'sample1', 'sales_count': 12}”
    • 我建议您使用映射和一两个示例文档来更新您的问题
    • 也就是说,如果您在“商店 2”中销售了 36 次产品“样品 1”,那么您将拥有同一产品的另一份文件,对吗?
    猜你喜欢
    • 1970-01-01
    • 2013-07-24
    • 2021-05-24
    • 2022-01-06
    • 2021-11-24
    • 2010-12-06
    • 2021-07-13
    • 2011-02-13
    • 1970-01-01
    相关资源
    最近更新 更多