Elasticsearch - 计算索引中所有文本中的单词出现次数
Elasticsearch - count word occurrences in all texts from index
我需要从索引 Y 中的所有文本中获取单词 X 的计数,索引 Y 只有一个字段“内容”。请注意,我需要计算特定单词的数量,它在所有文档中总共出现了多少次。我发现 ES 对此没有很好的优化(因为这是一种文本类型),但这是大学作业,所以我别无选择。
到目前为止我已经尝试过(取自here):
{
"script_fields": {
"phrase_Count": {
"script": {
"lang": "painless",
"source": "int count = 0; if(doc['content.keyword'].size() > 0 && doc['content'].value.indexOf(params.phrase)!=-1) count++; return count;",
"params": {
"phrase": "ustawa"
}
}
}
}
}
脚本方法returns:
{
"error": {
"root_cause": [
{
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:88)",
"org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:40)",
"if(doc['content.keyword'].size() > 0 && doc['content'].value.indexOf(params.phrase)!=-1) ",
" ^---- HERE"
],
"script": "int count = 0; if(doc['content.keyword'].size() > 0 && doc['content'].value.indexOf(params.phrase)!=-1) count++; return count;",
"lang": "painless",
"position": {
"offset": 22,
"start": 15,
"end": 104
}
}
],
"type": "search_phase_execution_exception",
"reason": "all shards failed",
"phase": "query",
"grouped": true,
"failed_shards": [
{
"shard": 0,
"index": "bills",
"node": "MXtcD7-zT-mhDyxMeRTMLw",
"reason": {
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:88)",
"org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:40)",
"if(doc['content.keyword'].size() > 0 && doc['content'].value.indexOf(params.phrase)!=-1) ",
" ^---- HERE"
],
"script": "int count = 0; if(doc['content.keyword'].size() > 0 && doc['content'].value.indexOf(params.phrase)!=-1) count++; return count;",
"lang": "painless",
"position": {
"offset": 22,
"start": 15,
"end": 104
},
"caused_by": {
"type": "illegal_argument_exception",
"reason": "No field found for [content.keyword] in mapping with types []"
}
}
}
]
},
"status": 400
}
上面使用了 content.keyword
,因为使用普通的 content
ES 抱怨文本类型没有针对此类搜索进行优化。
我也尝试过使用文本统计(来自 here),但我无法让它工作,它只计算带有单词的文档(这不是我要找的)。
作为我最后的方法,我尝试使用聚合搜索(来自 ),但它也只返回文档数,而不是单词:
{
"query": {
"query_string": {
"fields": ["content"],
"query": "ustawa"
}
},
"aggs": {
"my-terms": {
"terms": {
"field": "content.keyword"
}
}
}
}
我怎样才能做到这一点?如果重要的话,我正在使用 Python。
编辑
我正在使用的索引映射:
"mappings": {
"properties": {
"content": {
"type": "text",
"analyzer": "my_analyzer"
}
}
}
在 Elasticsearch 7.11 中匿名 runtime_mappings。使用此功能,您可以在运行时构建新字段,然后使用常规“总和”聚合计算所有文档中的单词数。
例如:
PUT test/_doc/1
{
"field" : "test test test ss"
}
PUT test/_doc/2
{
"field" : "test test test ss"
}
GET test/_search
{
"size": 0,
"runtime_mappings": {
"phrase_count": {
"type": "long",
"script": """
String tmp = doc['field.keyword'].value;
Matcher m = /(test)/.matcher(tmp);
int count = 0;
while (m.find()){
count++;
}
emit(count);
"""
}
},
"query": {
"match_all": {}
},
"aggs": {
"word_count": {
"sum": {
"field": "phrase_count"
}
}
}
}
匹配器中的“测试”字,就是你要找的,要算的。
Elasticsearch 中的 API 中有一个内置功能可以检索此类信息,因为文档和术语频率与 Elasticsearch 中的 BM25 评分非常相关。请参阅 Term vectors API and the term statistics 选项。您正在寻找“总词频”值。
如果您只想return特定术语的术语统计而不是现有文档中的所有术语,您可以发送一个“artifical document”到api只包含您正在查找的条款。
我需要从索引 Y 中的所有文本中获取单词 X 的计数,索引 Y 只有一个字段“内容”。请注意,我需要计算特定单词的数量,它在所有文档中总共出现了多少次。我发现 ES 对此没有很好的优化(因为这是一种文本类型),但这是大学作业,所以我别无选择。
到目前为止我已经尝试过(取自here):
{
"script_fields": {
"phrase_Count": {
"script": {
"lang": "painless",
"source": "int count = 0; if(doc['content.keyword'].size() > 0 && doc['content'].value.indexOf(params.phrase)!=-1) count++; return count;",
"params": {
"phrase": "ustawa"
}
}
}
}
}
脚本方法returns:
{
"error": {
"root_cause": [
{
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:88)",
"org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:40)",
"if(doc['content.keyword'].size() > 0 && doc['content'].value.indexOf(params.phrase)!=-1) ",
" ^---- HERE"
],
"script": "int count = 0; if(doc['content.keyword'].size() > 0 && doc['content'].value.indexOf(params.phrase)!=-1) count++; return count;",
"lang": "painless",
"position": {
"offset": 22,
"start": 15,
"end": 104
}
}
],
"type": "search_phase_execution_exception",
"reason": "all shards failed",
"phase": "query",
"grouped": true,
"failed_shards": [
{
"shard": 0,
"index": "bills",
"node": "MXtcD7-zT-mhDyxMeRTMLw",
"reason": {
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:88)",
"org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:40)",
"if(doc['content.keyword'].size() > 0 && doc['content'].value.indexOf(params.phrase)!=-1) ",
" ^---- HERE"
],
"script": "int count = 0; if(doc['content.keyword'].size() > 0 && doc['content'].value.indexOf(params.phrase)!=-1) count++; return count;",
"lang": "painless",
"position": {
"offset": 22,
"start": 15,
"end": 104
},
"caused_by": {
"type": "illegal_argument_exception",
"reason": "No field found for [content.keyword] in mapping with types []"
}
}
}
]
},
"status": 400
}
上面使用了 content.keyword
,因为使用普通的 content
ES 抱怨文本类型没有针对此类搜索进行优化。
我也尝试过使用文本统计(来自 here),但我无法让它工作,它只计算带有单词的文档(这不是我要找的)。
作为我最后的方法,我尝试使用聚合搜索(来自
{
"query": {
"query_string": {
"fields": ["content"],
"query": "ustawa"
}
},
"aggs": {
"my-terms": {
"terms": {
"field": "content.keyword"
}
}
}
}
我怎样才能做到这一点?如果重要的话,我正在使用 Python。
编辑 我正在使用的索引映射:
"mappings": {
"properties": {
"content": {
"type": "text",
"analyzer": "my_analyzer"
}
}
}
在 Elasticsearch 7.11 中匿名 runtime_mappings。使用此功能,您可以在运行时构建新字段,然后使用常规“总和”聚合计算所有文档中的单词数。
例如:
PUT test/_doc/1
{
"field" : "test test test ss"
}
PUT test/_doc/2
{
"field" : "test test test ss"
}
GET test/_search
{
"size": 0,
"runtime_mappings": {
"phrase_count": {
"type": "long",
"script": """
String tmp = doc['field.keyword'].value;
Matcher m = /(test)/.matcher(tmp);
int count = 0;
while (m.find()){
count++;
}
emit(count);
"""
}
},
"query": {
"match_all": {}
},
"aggs": {
"word_count": {
"sum": {
"field": "phrase_count"
}
}
}
}
匹配器中的“测试”字,就是你要找的,要算的。
Elasticsearch 中的 API 中有一个内置功能可以检索此类信息,因为文档和术语频率与 Elasticsearch 中的 BM25 评分非常相关。请参阅 Term vectors API and the term statistics 选项。您正在寻找“总词频”值。
如果您只想return特定术语的术语统计而不是现有文档中的所有术语,您可以发送一个“artifical document”到api只包含您正在查找的条款。