我有一个使用术语聚合的弹性搜索查询:
{
"query" : {
"match_all" : {}
},
"aggregations" : {
"tag" : {
"terms" : {
"field": "persona"
}
}
}
}
查询结果中的样本命中的_source如下所示:
"_source": {
"facets": {
"persona": "research manager",
"research type": "qualitative"
},
"name": "Joe Doe"
}
聚合桶看起来像:
"facets": {
"tag": {
"_type": "terms",
"missing": 0,
"other": 0,
"terms": [
{
"count": 2,
"term": "research"
},
{
"count": 2,
"term": "manager"
}
],
"total": 4
}
}
术语聚合正在考虑角色字段中的单词而不是字段的整个值。这是预期的输出:
...
"terms" : [
{
"term" : "research manager",
"count" : 2
},
...
]
....
我做错了吗?有没有办法实现这个目标?
答案 0 :(得分:4)
正如bittusarkar所提到的,人物角色最有可能被分析。如果您未在映射中指定该字段的映射或信息,则Elasticsearch会将其动态添加到映射中,类型为string
,默认为Standard Analyzer。分析器包含标准的标记器,它比空白标记器更多,但基本上你的字段内容被视为一个单词"。
通常,对于全文搜索/ Elasticsearch查询,您确实希望对内容进行分析,以便您可以匹配"研究经理"当你搜索"经理"例如。
一种解决方案是使用multi-fields。关于角色字段的映射片段可能如下所示:
"persona": {
"type": "multi_field",
"fields": {
"persona": { "type": "string" },
"raw": { "type": "string", "index": "not_analyzed" }
}
}
这样你就可以进行搜索:
{
"query" : {
"match" : {
"persona" : "Managers"
}
}
}
同时您可以使用聚合:
{
"query" : {
"match_all" : {}
},
"aggregations" : {
"tag" : {
"terms" : {
"field": "persona.raw"
}
}
}
}
请注意,您使用persona
代替persona.raw
代替聚合这一术语。
答案 1 :(得分:1)
最有可能对“人物角色”字段进行分析。映射“样本”的定义应该确认它。 Terms aggregation
适用于未分析的字段。如果分析字段“persona”,则将其作为两个不同的单词“research”和“manager”保存在索引中。为了获得你想要的东西,你必须将字段“persona”更改为未分析。有关详细信息,请参阅this。我担心你不能动态地在映射中进行这种改变。您需要使用更新的映射重新索引所有文档,以使更改生效。