我有以下ElasticSearch查询:
{
"from": 0,
"sort": [
"_score"
],
"fields": [
"id",
"title",
"text"
],
"query": {
"query_string": {
"fields": [
"title",
"text"
],
"query": "(\"green socks\" OR \"red socks\") AND NOT (\"yellow\" OR \"blue\")"
}
},
"size": 100
}
这很好用,并返回一组大约80,000个文档的文档。
我想在这组80,000份文件(即与"query": "(\"green socks\" OR \"red socks\") AND NOT (\"yellow\" OR \"blue\")")
匹配的文件集上计算以下内容:
这感觉就像一个聚合查询,但我无法看到它 任何帮助v感激不尽,
谢谢,
R
答案 0 :(得分:1)
你猜对了。这是聚合的工作。但如果您的映射不正确,聚合可能会很慢。例如,如果您对分析的字段(如“text”)进行聚合,这可能包含大量令牌,则会导致内存使用率过高,从而影响性能。
现在找到你的要求,你想要在80000结果的集合中包含说“红袜子”的文件的数量。您希望术语出现在任何位置(标题或文本字段中的表示)或仅存在于特定字段中。如果您希望它在任何字段中,那么您需要首先将字段组合在一个字段中。
您可以使用简单的terms aggregation以及您的查询,该查询将提供该字段中所有字词的计数。
{
.................
"query": {
"query_string": {
"fields": [
"title",
"text"
],
"query": "(\"green socks\" OR \"red socks\") AND NOT (\"yellow\" OR \"blue\")"
}
},
"aggs" : {
"my-terms" : {
"terms" : {
"field" : "title"
}
}
}
"size": 100
}
如果您只想将某些术语计为“红袜子”“绿袜子”等,那么您应该使用filters aggregation
{
.................
"query": {
"query_string": {
"fields": [
"title",
"text"
],
"query": "(\"green socks\" OR \"red socks\") AND NOT (\"yellow\" OR \"blue\")"
}
},
"aggs" : {
"my-terms" : {
"filters" : {
"filters" : {
"red socks" : { "term" : { "title" : "red sock" }},
"green sock" : { "term" : { "title" : "green sock" }},
......
and so on...
}
}
}
"size": 100
}
请注意,正如我之前提到的,字段映射会影响聚合的性能和内存要求。
答案 1 :(得分:0)
除非你真的有exabytes数据,否则我建议使用Lucene而不是ElasticSearch来减少开销。当您可以更有效地直接访问JSON中的数据并通过网络发送数据时,没有用处...
除非您要加载80000个文档,否则我建议您再发送两个请求:
"green socks" AND NOT ("yellow" OR "blue")
"red socks" AND NOT ("yellow" OR "blue")
获取您感兴趣的计数。
可以一次完成所有这三项工作 - 如果您深入研究Lucene API,而不是通过文本搜索API。它是所有设置的交叉点,没什么了不起的。但同样,您不希望在不需要的情况下通过网络传输此类数据。