我目前正试图在弹性搜索中做一些奇特的事情......它几乎可以工作。
使用案例:我必须将某个字段的结果数量限制为(x)结果。
示例:在一组餐厅中,我只想为每个餐馆名称返回两个位置。如果我搜索墨西哥食物,那么我应该得到(x)Taco Bell命中,(x)Del Taco Hits和(x)El Torito Hits。
问题:我的聚合目前仅匹配该术语的部分内容。
For Instance:如果我尝试匹配company_name
,它会为 taco 创建一个存储桶,为 bell 创建另一个存储桶因此,Taco Bell可能会出现在2个桶中,从而导致该公司获得(x) * 2
个结果。
我发现很难相信这是理想的行为。有没有办法按整个搜索词聚合?
这是我当前的聚合JSON:
"aggs": {
"by_company": {
"terms": {
"field": "company_name"
},
"aggs": {
"first_hit": {
"top_hits": {"size":1, "from": 0}
}
}
}
}
非常感谢您的帮助!
答案 0 :(得分:2)
是。如果您的“company_name”只是标准分析器的常规字符串,或者您使用的“company_name”分析器正在分割名称,那么这就是您的答案。 ES存储“术语”,而不是单词或整个文本,除非您告诉它。
假设您对该字段的当前分析器完全按照上面描述的那样进行,那么您需要另一个 - 让我们称之为“原始” - 应该镜像您的company_name
字段的字段,但它应该按原样存储公司名称。
这就是我的意思:
{
"mappings": {
"test": {
"properties": {
...,
"company_name": {
"type": "multi_field",
"fields": {
"company_name": {
"type": "string" #and whatever you currently have in your mapping for `company_name`
},
"raw": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
}
}
在你的查询中,你会这样做:
"aggs": {
"by_company": {
"terms": {
"field": "company_name.raw"
},
"aggs": {
"first_hit": {
"top_hits": {"size":1, "from": 0}
}
}
}
}