如何在Elasticsearch和聚合中执行和查询

时间:2019-07-25 09:29:49

标签: elasticsearch aggregation

我有product_supplier索引,其中包含产品及其供应商。我已经给了供应商名称,并且我想得到由给定供应商提供的产品。 例如。我给了供应商“ supplier1”和“ supplier2”。我想获得该供应商提供的“芯片”和“芒果”产品。之后,我要汇总产品名称。这是我的总点击量。

"hits":[
      {
        "_index": "products_supplier",
        "_type": "_doc",
        "_id": "1",
        "_score": 1.0,
        "_source": {
          "product_name": "maggie",
          "product_supplier": "supplier1"
        }
      },
      {
        "_index": "products_supplier",
        "_type": "_doc",
        "_id": "2",
        "_score": 1.0,
        "_source": {
          "product_name": "maggie",
          "product_supplier": "supplier2"
        }
      },
      {
        "_index": "products_supplier",
        "_type": "_doc",
        "_id": "3",
        "_score": 1.0,
        "_source": {
          "product_name": "potatoes",
          "product_supplier": "supplier1"
        }
      },
      {
        "_index": "products_supplier",
        "_type": "_doc",
        "_id": "4",
        "_score": 1.0,
        "_source": {
          "product_name": "chips",
          "product_supplier": "supplier1"
        }
      },
      {
        "_index": "products_supplier",
        "_type": "_doc",
        "_id": "5",
        "_score": 1.0,
        "_source": {
          "product_name": "maggie",
          "product_supplier": "supplier3"
        }
      },
      {
        "_index": "products_supplier",
        "_type": "_doc",
        "_id": "6",
        "_score": 1.0,
        "_source": {
          "product_name": "mango",
          "product_supplier": "supplier1"
        }
      },
      {
        "_index": "products_supplier",
        "_type": "_doc",
        "_id": "7",
        "_score": 1.0,
        "_source": {
          "product_name": "chips",
          "product_supplier": "supplier2"
        }
      },
      {
        "_index": "products_supplier",
        "_type": "_doc",
        "_id": "8",
        "_score": 1.0,
        "_source": {
          "product_name": "chips",
          "product_supplier": "supplier3"
        }
      }
    ]

我有这样的查询

GET /products_supplier/_search
{
 "query": {
   "bool": {
     "should": [
       {"term": {
         "product_supplier": {
           "value": "supplier2"
         }
       }},
       {"term": {
         "product_supplier": {
           "value": "supplier1"
         }
       }}
     ]
   }
 }, "aggs": {
   "product_name": {
    "terms": {
      "field": "product_name.keyword"
    }
   }
 }
}

我知道了

"hits" : {
    "total" : {
      "value" : 6,
      "relation" : "eq"
    },
    "max_score" : 1.3862944,
    "hits" : [
      {
        "_index" : "products_supplier",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.3862944,
        "_source" : {
          "product_name" : "maggie",
          "product_supplier" : "supplier2"
        }
      },
      {
        "_index" : "products_supplier",
        "_type" : "_doc",
        "_id" : "7",
        "_score" : 1.3862944,
        "_source" : {
          "product_name" : "chips",
          "product_supplier" : "supplier2"
        }
      },
      {
        "_index" : "products_supplier",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.7985077,
        "_source" : {
          "product_name" : "maggie",
          "product_supplier" : "supplier1"
        }
      },
      {
        "_index" : "products_supplier",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 0.7985077,
        "_source" : {
          "product_name" : "potatoes",
          "product_supplier" : "supplier1"
        }
      },
      {
        "_index" : "products_supplier",
        "_type" : "_doc",
        "_id" : "4",
        "_score" : 0.7985077,
        "_source" : {
          "product_name" : "chips",
          "product_supplier" : "supplier1"
        }
      },
      {
        "_index" : "products_supplier",
        "_type" : "_doc",
        "_id" : "6",
        "_score" : 0.7985077,
        "_source" : {
          "product_name" : "mango",
          "product_supplier" : "supplier1"
        }
      }
    ]
  },
  "aggregations" : {
    "product_name" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "chips",
          "doc_count" : 2
        },
        {
          "key" : "maggie",
          "doc_count" : 2
        },
        {
          "key" : "mango",
          "doc_count" : 1
        },
        {
          "key" : "potatoes",
          "doc_count" : 1
        }
      ]
    }
  }
}

我只喜欢获得“芒果”和“薯条”产品名称

1 个答案:

答案 0 :(得分:0)

您只需一一分解需求。下面是AND / OR形式的查询的基本表示形式:

(供应商1或供应商2)AND(芒果OR芯片)

下面的查询只是上面的ES查询表示。只需将OR替换为should子句,而将AND替换为must子句,您应该能够获得所需的结果:

查询请求

POST products_supplier/_search
{  
   "query":{  
      "bool":{
        "must": [
          {
            "bool": {
              "should": [
                {
                  "term": {
                    "product_name.keyword": {
                      "value": "mango"
                    }
                  }
                },
                {
                  "term": {
                    "product_name.keyword": {
                      "value": "chips"
                    }
                  }
                }
              ],
              "minimum_should_match": 1
            }
          },
          {
            "bool": {
              "should": [
                {
                  "term": {
                    "product_supplier.keyword": {
                      "value": "supplier1"
                    }
                  }
                },
                {
                  "term": {
                    "product_supplier.keyword": {
                      "value": "supplier2"
                    }
                  }
                }
              ],
              "minimum_should_match": 1
            }
          }
        ]
      }
   },
   "aggs":{  
      "product_name":{  
         "terms":{  
            "field":"product_name.keyword"
         }
      }
   }
}

请注意,在上述查询中,您正在寻找完全匹配的内容,在这种情况下,我建议您使用该字段的keyword兄弟姐妹。

我还提到了minimum_should_match: 1,这意味着相应的文档仅在封闭的should子句中的任何一个值匹配时才返回。

查询响应:

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 3,
    "max_score": 1.4508328,
    "hits": [
      {
        "_index": "products_supplier",
        "_type": "_doc",
        "_id": "4",
        "_score": 1.4508328,
        "_source": {
          "product_name": "chips",
          "product_supplier": "supplier1"
        }
      },
      {
        "_index": "products_supplier",
        "_type": "_doc",
        "_id": "6",
        "_score": 1.4508328,
        "_source": {
          "product_name": "mango",
          "product_supplier": "supplier1"
        }
      },
      {
        "_index": "products_supplier",
        "_type": "_doc",
        "_id": "7",
        "_score": 1.3862944,
        "_source": {
          "product_name": "chips",
          "product_supplier": "supplier2"
        }
      }
    ]
  },
  "aggregations": {
    "product_name": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "chips",
          "doc_count": 2
        },
        {
          "key": "mango",
          "doc_count": 1
        }
      ]
    }
  }
}

希望这会有所帮助!