【问题标题】:Elastic Search Query for Distinct Nested Values不同嵌套值的弹性搜索查询
【发布时间】:2018-09-28 00:20:44
【问题描述】:

我正在为 Elastic Search 6.2.2 使用高级 REST 客户端。假设我在索引“DOCUMENTS”中有两个文档,类型为“DOCUMENTS”,它们是

{
   "_id": 1,
   "Name": "John",
   "FunFacts": {
       "FavColor": "Green",
       "Age": 32
   }
},
{
   "_id": 2,
   "Name": "Amy",
   "FunFacts": {
       "FavFood": "Pizza",
       "Age": 33
   }
}

我想找出所有不同的有趣事实及其不同的价值,最终返回

{
    "FavColor": ["Green"],
    "Age": [32, 33],
    "FavFood": ["Pizza"]
}

这可以要求对 Elastic Search 进行多个查询,但我更喜欢只有一个查询。此外,Elastic Search 索引可能会变得相当大,因此我必须在 ES 实例上强制执行尽可能多的操作。

此代码似乎生成了一个仅包含 FunFacts 的文档列表,但我仍必须自己执行聚合,这非常非常不理想。

SearchRequest searchRequest = new SearchRequest("DOCUMENTS");
searchRequest.types("DOCUMENTS");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
String [] includes = new String[1];
includes[0] = "FunFacts";
String [] excludes = new String[1];
excludes[0] = "Name";
searchSourceBuilder.fetchSource(includes, excludes);
searchRequest.source(searchSourceBuilder);

SearchResponse searchResponse =
    restHighLevelClient.search(searchRequest);

谁能指出我正确的方向?我注意到几乎所有的 Elastic Search 文档都以 curl 命令的形式出现,这对我没有帮助,因为我不够精通将这些命令翻译成 JAVA。

这是你的情节转折。由于允许用户决定他们的有趣事实,我们无法提前知道FunFacts Map 中的键是什么。 :/

谢谢, 马特

【问题讨论】:

    标签: elasticsearch solr elasticsearch-5 spring-data-elasticsearch elasticsearch-6


    【解决方案1】:

    您可以使用聚合在一个查询中完成所有操作。假设您的索引中有以下文档

    {
       "Name": "Jake",
       "FunFacts": {
           "FavFood": "Burgers",
           "Age": 32
       }
    }
    
    {
       "Name": "Amy",
       "FunFacts": {
           "FavFood": "Pizza",
           "Age": 33
       }
    }
    
    {
       "Name": "Alex",
       "FunFacts": {
           "FavFood": "Burgers",
           "Age": 28
       }
    }
    

    ,并且您想获得不同的“FavFood”选择,您可以使用以下术语聚合 (docs on this topic)

    {
      "aggs": {
        "disticnt_fun_facts": {
          "terms": { "field": "FunFacts.FavFood" }
        }
      }
    }
    

    ,这将导致一些类似的事情

    {
      ...
      "hits": { ... },
      "aggregations": {
        "disticnt_fun_facts": {
          "doc_count_error_upper_bound": 0,
          "sum_other_doc_count": 0,
          "buckets": [
            {
              "key": "burgers",
              "doc_count": 2
            },
            {
              "key": "pizza",
              "doc_count": 1
            }
          ]
        }
      }
    }
    

    为简洁起见,我只是将 aggregations 部分留在了结果响应中,因此需要注意的重要一点是 buckets 数组,它代表找到的每个不同的术语,key,以及它们在您的文档中出现的次数,doc_count。

    希望对您有所帮助。

    【讨论】:

    • 谢谢@falomir!有没有办法列出所有不同 FunFacts 对象中的所有键?例如,返回{"FavFood", "Age", "FavColor"}。
    • 首先,我决定将文档展平。其次,我使用包含 "FavFood" : { "type" : "keyword" } 的命令创建索引并收到错误消息 {"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"Fielddata is disabled on text fields by default. Set fielddata=true on [FavFood] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead."}]," 。为什么我会收到此消息,我该怎么做才能解决此问题?
    • 我在elastic.co/blog/strings-are-dead-long-live-strings 找到了上述评论的一个很好的答案。
    • 为了能够对文本字段进行排序和聚合,您需要在该字段上启用“fielddata”。默认情况下,文本字段上的 Fielddata 是禁用的,您可以在此处阅读更多有关原因的信息 elastic.co/guide/en/elasticsearch/reference/current/… 以及如何修改现有映射以启用它。
    猜你喜欢
    • 2021-09-01
    • 2015-09-24
    • 2017-06-11
    • 2020-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多