ElasticSearch:计算一组文档中一组单词的出现频率
ElasticSearch: Count Frequency of Occurrence of a Set of Words in a Set of Documents
我有以下 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
}
这很好用,returns 一组大约有 80,000 个文档的文档。
我想根据这组 80,000 个文档计算以下内容(即匹配 "query": "(\"green socks\" OR \"red socks\") AND NOT (\"yellow\" OR \"blue\")")
的文档集:
- 对于每个 "green socks" 计算编号。 80,000 份文件中至少有一次包含 "green socks"。
- 对于每个 "red socks" 计算编号。 80,000 份文件中至少有一次包含 "red socks"。
- 依此类推,对于上述查询字符串 "left-hand" 侧的所有其他 words/phrases。
- 实际上每个查询字符串中大约有 50 - 100 个这样的 words/phrases,所以查询字符串中还有另一个这样的 50 - 100 "red socks" words/phrases 我实际上是 运行.
这感觉像是一个聚合查询,但我就是看不出来。
非常感谢收到的任何帮助,
谢谢,
除非您真的有 EB 级数据,否则我建议使用 Lucene 而不是 ElasticSearch 来减少开销。当您可以更有效地直接访问数据时,序列化 JSON 中的数据并通过网络发送它是没有用的...
除非你想加载80000个文档,否则我建议你再发送两个请求:
"green socks" AND NOT ("yellow" OR "blue")
"red socks" AND NOT ("yellow" OR "blue")
获取您感兴趣的计数。
如果您深入研究 Lucene API,而不是通过文本搜索 API,则可以同时执行所有这三个操作。都是固定的路口,没什么了不起的。但同样,您不想在没有必要的情况下通过网络传输此类数据。
你猜对了。这是聚合的工作。但是如果您的映射不正确,聚合可能会很慢。例如,如果您对像 "text" 这样的分析字段进行聚合,它可能包含大量标记,这将导致高内存使用率,进而影响性能。
现在您的要求是,您希望在 80000 个结果集中包含 "red sock" 的文档数。您希望术语出现在任何地方(意味着在标题或文本字段中)或仅出现在特定字段中。如果您希望它在任何字段中,那么您需要先将这些字段合并到一个字段中。
您可以将简单的 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
}
如果您只想计算某些术语集,如 "red socks" "green sock" 等,那么您应该使用 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
}
需要注意的是,正如我之前提到的,字段映射会影响聚合的性能和内存要求。
我有以下 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
}
这很好用,returns 一组大约有 80,000 个文档的文档。
我想根据这组 80,000 个文档计算以下内容(即匹配 "query": "(\"green socks\" OR \"red socks\") AND NOT (\"yellow\" OR \"blue\")")
的文档集:
- 对于每个 "green socks" 计算编号。 80,000 份文件中至少有一次包含 "green socks"。
- 对于每个 "red socks" 计算编号。 80,000 份文件中至少有一次包含 "red socks"。
- 依此类推,对于上述查询字符串 "left-hand" 侧的所有其他 words/phrases。
- 实际上每个查询字符串中大约有 50 - 100 个这样的 words/phrases,所以查询字符串中还有另一个这样的 50 - 100 "red socks" words/phrases 我实际上是 运行.
这感觉像是一个聚合查询,但我就是看不出来。
非常感谢收到的任何帮助,
谢谢,
除非您真的有 EB 级数据,否则我建议使用 Lucene 而不是 ElasticSearch 来减少开销。当您可以更有效地直接访问数据时,序列化 JSON 中的数据并通过网络发送它是没有用的...
除非你想加载80000个文档,否则我建议你再发送两个请求:
"green socks" AND NOT ("yellow" OR "blue")
"red socks" AND NOT ("yellow" OR "blue")
获取您感兴趣的计数。
如果您深入研究 Lucene API,而不是通过文本搜索 API,则可以同时执行所有这三个操作。都是固定的路口,没什么了不起的。但同样,您不想在没有必要的情况下通过网络传输此类数据。
你猜对了。这是聚合的工作。但是如果您的映射不正确,聚合可能会很慢。例如,如果您对像 "text" 这样的分析字段进行聚合,它可能包含大量标记,这将导致高内存使用率,进而影响性能。
现在您的要求是,您希望在 80000 个结果集中包含 "red sock" 的文档数。您希望术语出现在任何地方(意味着在标题或文本字段中)或仅出现在特定字段中。如果您希望它在任何字段中,那么您需要先将这些字段合并到一个字段中。
您可以将简单的 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
}
如果您只想计算某些术语集,如 "red socks" "green sock" 等,那么您应该使用 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
}
需要注意的是,正如我之前提到的,字段映射会影响聚合的性能和内存要求。