在Elasticsearch中为每个条件获取一个文档

问题描述:

我有这个有点复杂的ElasticSearch查询有5个条件,每个条件需要1个文档,另外还有1个文档不能返回两个条件。在Elasticsearch中为每个条件获取一个文档

所以我尝试了两种不同的方法

首个多搜索

GET /products/_msearch 
{} 
{"query": {"function_score":{"query":{"bool":{"must":{ "match": 
{"category":"1"}},"must_not":[{"ids":{"values": 
["7DhlWxCY4oQyo8884AIS4Y","3fy0uSuMROSoCQueGA2uO4"]}}]}}, 
"random_score":{"seed":1376718000}}},"from":0,"size":1} 
{} 
{"query": {"function_score":{"query":{"bool":{"must":{ "match": 
{"category":"2"}},"must_not":[{"ids":{"values": 
["7DhlWxCY4oQyo8884AIS4Y","3fy0uSuMROSoCQueGA2uO4"]}}]}}, 
"random_score":{"seed":1376718000}}},"from":0,"size":1} 

所以我需要从第1类和2类每个查询1级的产品,但我需要过滤,我已经购买的所有产品,另外产品可以同时属于第1类和第2类,但我不希望从这两个查询中收到同样的产品。

但是我写的这个查询实际上可以从两个类别中返回相同的产品。

第二条本办法我真是,我试图寻找普通这样

GET /products/product/_search 
{ 
    "query": { 
     "bool": { 
      "must":{ 
       "bool": { 
        "must":[ 
         { "match":{"category":"1"} } , 
         { "match":{"category":"2"} } 
        ] 
       } 
      }, 
      "must_not": [{ 
       "ids": { 
        "values": [ 
         "7DhlWxCY4oQyo8884AIS4Y", 
         "3fy0uSuMROSoCQueGA2uO4" 
        ] 
       } 
      }] 
     } 
    } 
} 

但是这当然会在这两个类别只返回产品。

所以任何想法如何从每个类别排除产品之一,已经购买

根据由Val发表评论我想出了这个查询

GET /products/product/_search 
{ 
    "aggs" : { 
    "categories" : { 
     "terms" : { "field" : "category" }, 
     "aggs": { 
      "top": { 
       "top_hits": { 
        "size" : 1 
       } 
      } 
     } 
    } 
    } 
} 
完成我的情况

  • 一个独特的产品

    但是这只是返回一切,所以我想我做的事情非常错误,但我刚开始使用ES工作,而我说不准什么

+0

如何在类别字段上使用“terms”聚合,然后使用size = 1的'top_hits'子聚合?这可能会达到你想要的。 – Val

+0

你能给我参考文档或例子吗? –

+0

条款agg:https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html + top_hits agg:https://www.elastic.co/guide /en/elasticsearch/reference/current/search-aggregations-metrics-top-hits-aggregation.html – Val

试试这个:

{ 
    "size": 0, 
    "aggregations": { 
    "myAgg": { 
     "filters": { 
     "filters": { 
      "cat1": { 
      "term": { 
       "category": "1" 
      } 
      }, 
      "cat2": { 
      "term": { 
       "category": "2" 
      } 
      } 
     } 
     }, 
     "aggregations": { 
     "top": { 
      "top_hits": { 
      "size": 1 
      } 
     } 
     } 
    } 
    } 
} 

,你会得到两个桶,一个用于每个分类均具有准确一击每个。

如果你想扩展您的每一个类别的搜索,并通过特定的字段排除,试试这个:

{ 
    "size": 0, 
    "aggregations": { 
    "myAgg": { 
     "terms": { 
     "field": "category" 
     }, 
     "aggregations": { 
     "bool_agg": { 
      "filter": { 
      "bool": { 
       "must_not": { 
       "terms": { 
        "ids": [ 
        "7DhlWxCY4oQyo8884AIS4Y", 
        "3fy0uSuMROSoCQueGA2uO4" 
        ] 
       } 
       } 
      } 
      }, 
      "aggregations": { 
      "top": { 
       "top_hits": { 
       "size": 1 
       } 
      } 
      } 
     } 
     } 
    } 
    } 
} 

现在你会得到桶每个类别有关搜索的一个最高命中。

+0

谢谢。第一个仍然给重复。因此,我在两个桶中获得具有相同ID的产品,第二个给我一个错误:默认情况下,Fielddata在文本字段上处于禁用状态。在[levels]上设置fielddata = true,以便通过取消倒置索引来加载内存中的fielddata。请注意,这可以使用大量的内存' –

+0

好吧,我想这与你的映射和文件在你的群集中的索引方式有关。我建议你阅读[this](https://www.elastic.co/guide/en/elasticsearch/reference/current/fielddata.html)和[this](https://github.com/10up/ElasticPress/问题/ 643) – Eli