假设我有这个给定的数据
{
"name" : "ABC",
"favorite_cars" : [ "ferrari","toyota" ]
}, {
"name" : "ABC",
"favorite_cars" : [ "ferrari","toyota" ]
}, {
"name" : "GEORGE",
"favorite_cars" : [ "honda","Hyundae" ]
}
当我搜索最喜欢丰田车的人时,每当我查询这个数据时,它都会返回这个数据
{
"name" : "ABC",
"favorite_cars" : [ "ferrari","toyota" ]
}, {
"name" : "ABC",
"favorite_cars" : [ "ferrari","toyota" ]
}
结果是两个名为ABC的记录。如何只选择不同的文档?我想得到的结果只有这个
{
"name" : "ABC",
"favorite_cars" : [ "ferrari","toyota" ]
}
这是我的问题
{
"fuzzy_like_this_field" : {
"favorite_cars" : {
"like_text" : "toyota",
"max_query_terms" : 12
}
}
}
我正在使用ElasticSearch 1.0.0。使用java api客户端
@JRL几乎是正确的。您需要在查询中进行聚合。这将为您提供对象中按发生顺序排序的前10000个“favorite_cars”的列表。
{
"query":{ "match_all":{ } },
"size":0,
"Distinct" : {
"Cars" : {
"terms" : { "field" : "favorite_cars", "order": { "_count": "desc"}, "size":10000 }
}
}
}
还值得注意的是,为了得到“迈凯轮F1”而不是“迈凯轮”、“F1”,您不希望对“favorite_car”字段进行分析。
"favorite_car": {
"type": "string",
"index": "not_analyzed"
}
ElasticSearch不提供任何查询,您可以通过该查询根据字段值获取不同的文档。
理想情况下,您应该为具有相同类型和id的同一文档编制索引,因为ElasticSearch使用这两件事为文档提供唯一id。唯一id很重要,这不仅是因为它可以检测重复文档,还可以在进行任何修改时更新同一文档,而不是插入新文档。有关索引文档的更多信息,请阅读本文。
但肯定有解决你问题的办法。由于您使用的是java api客户端,因此可以根据字段值自行删除重复文档。事实上,它使您能够更灵活地对从ES获得的响应执行自定义操作。
SearchResponse response = client.prepareSearch().execute().actionGet();
SearchHits hits = response.getHits();
Iterator<SearchHit> iterator = hits.iterator();
Map<String, SearchHit> distinctObjects = new HashMap<String,SearchHit>();
while (iterator.hasNext()) {
SearchHit searchHit = (SearchHit) iterator.next();
Map<String, Object> source = searchHit.getSource();
if(source.get("name") != null){
distinctObjects.put(source.get("name").toString(),source);
}
}
因此,您的地图中将有一个独特的searchHit对象地图。
您还可以创建一个对象映射,并使用它代替SearchHit。
我希望这能解决你的问题。如果代码中有任何错误,请原谅我。这只是一个伪代码,让你明白如何解决你的问题。
谢谢
您可以使用聚合消除重复。使用术语聚合,结果将按一个字段分组,例如name
,还提供字段每个值出现的计数,并按此计数(降序)对结果进行排序。
{
"query": {
"fuzzy_like_this_field": {
"favorite_cars": {
"like_text": "toyota",
"max_query_terms": 12
}
}
},
"aggs": {
"grouped_by_name": {
"terms": {
"field": "name",
"size": 0
}
}
}
}
除了命中
之外,结果还将包含桶
,其唯一值在key
中,计数在doc_count
中:
{
"took" : 4,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 0.19178301,
"hits" : [ {
"_index" : "pru",
"_type" : "pru",
"_id" : "vGkoVV5cR8SN3lvbWzLaFQ",
"_score" : 0.19178301,
"_source":{"name":"ABC","favorite_cars":["ferrari","toyota"]}
}, {
"_index" : "pru",
"_type" : "pru",
"_id" : "IdEbAcI6TM6oCVxCI_3fug",
"_score" : 0.19178301,
"_source":{"name":"ABC","favorite_cars":["ferrari","toyota"]}
} ]
},
"aggregations" : {
"grouped_by_name" : {
"buckets" : [ {
"key" : "abc",
"doc_count" : 2
} ]
}
}
}
注意,由于重复消除和结果排序,使用聚合的成本将很高。
我试图解决一个问题,我必须在搜索中得到明确的结果。 当我对最喜欢的汽车“法拉利”执行术语查询时。我得到两个名为ABC的结果。在这种情况下,我只是希望返回的结果应该是一个。所以我的要求是,如果我可以应用一个不同的on name字段来接收一个1结果。 谢啦
问题内容: 我有一个看起来像这样的架构: 我想找到b的所有值,其中b的值由2个或更多实体共享: 查询依据: 应该返回和。 问题答案: 您可以使用2 的字段对字段进行聚合,然后添加子聚合以找到匹配的字段:
问题内容: 我有以下查询: 这将同时返回“匹配”对象(整个文档)和“ inner_hits”对象(嵌套在匹配内部)。 有没有办法让我只返回出现在“ inner_hits”结果中的匹配“查询”元素,而没有获取整个文档? 问题答案: 应该可以通过以下方式 在顶层 禁用source- field 来实现
elasticsearch实例的一些背景: 一个节点,在一台机器上 特定索引由大小为1.23TB的26亿文档组成 索引被分成4个碎片。 堆大小设置为30 GB 服务器有256GB内存和40个内核。 Elasticsearch(版本1.4.3)是这个服务器上唯一运行的东西 我想返回所有具有特定名称的文档。属性名称已映射为: 我尝试过使用不同类型的搜索;过滤器、查询字符串、术语。结果都一样。当前查询如
问题内容: 我想将查询发送给ELS,该查询仅返回总点击数。 没有别的 就像我得到回应一样 我只想打印731552 现在我只发送: 卷曲http:// server:9200 / games_profilder / _search 谢谢 问题答案: 您可以为此使用响应过滤: 这将产生 如果您真的只想得到总数,则可以使用以下方法传递结果: 那只会产生数字
问题内容: 搜索时,Elasticsearch返回包含各种元信息的数据结构。 实际结果集包含在从数据库返回的JSON结果内的“ hits”字段中。 Elasticsearch是否有可能仅返回所需的数据(然后是“ hits”字段的内容)而没有嵌入所有其他元数据中? 我知道我可以将结果解析为JSON并提取出来,但是我不希望复杂性,麻烦和性能下降。 谢谢! 这是Elasticsearch返回的数据结构的