不同嵌套值的弹性搜索查询

Elastic Search Query for Distinct Nested Values

我正在使用 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 地图中的键是什么。 :/

谢谢, 马特

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

{
   "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.

希望对您有所帮助。