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\")") 的文档集:

这感觉像是一个聚合查询,但我就是看不出来。
非常感谢收到的任何帮助,

谢谢,

除非您真的有 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
    }

需要注意的是,正如我之前提到的,字段映射会影响聚合的性能和内存要求。