我有一个带有嵌套文档集合的文档:
{
"_source": {
...
"groups": [
{
"group_id": 100,
"parent_group_id": 1,
"title": "Wheel",
"parent_group_title": "Parts"
},
{
"group_id": 200,
"parent_group_id": 2,
"title": "Seat",
"parent_group_title": "Parts"
}
]
...
}
}
映射将显示下一个:
{
...,
"groups": {
"type": "nested",
"properties": {
"group_id": {
"type": "long"
},
"title": {
"type": "text",
"analyzer": "my_custom_analyzer",
"term_vector": "with_positions_offsets",
"fields": {
"keyword": {
"type": "keyword"
}
}
},
"parent_group_id": {
"type": "long"
},
"parent_group_title": {
"type": "text",
"analyzer": "my_custom_analyzer",
"term_vector": "with_positions_offsets",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
},
...
}
我正在尝试做的是下一个聚合:
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "groups",
"query": {
"match": {
"groups.title": {
"query": "whe"
}
}
}
}
}
]
}
},
"size": 0,
"aggs": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"nested": {
"path": "groups",
"query": {
"match": {
"groups.title": {
"query": "whe"
}
}
}
}
}
]
}
},
"aggs": {
"groups": {
"nested": {
"path": "groups"
},
"aggs": {
"titles": {
"terms": {
"field": "groups.title.keyword",
"size": 5
},
"aggs": {
"parents": {
"terms": {
"field": "groups.parent_group_title.keyword",
"size": 3
}
}
}
}
}
}
}
}
}
}
通过这样的查询,我得到的结果类似于下一个:
"aggregations" : {
"filtered" : {
"doc_count" : ...,
"groups" : {
"doc_count" : ...,
"titles" : {
"doc_count_error_upper_bound" : ...,
"sum_other_doc_count" : ...,
"buckets" : [
{
"key" : "Seat",
"doc_count" : 10,
"parents" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 10,
"buckets" : [
{
"key" : "Parts",
"doc_count" : 6
},
{
"key" : "Other",
"doc_count" : 4
}
]
}
},
{
"key" : "Wheel",
"doc_count" : 3,
"parents" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 3,
"buckets" : [
{
"key" : "Parts",
"doc_count" : 2
},
{
"key" : "Other",
"doc_count" : 1
}
]
}
}
]
}
}
}
}
但是我想要的是,只有键
Wheel
的结果才会出现在结果存储桶中(或与whe
搜索字符串匹配的任何其他结果)。希望这个问题足够清楚。我做错了什么?有什么建议或变化的数据结构或查询吗?
UPD:
添加
my_custom_analyzer
供引用:{
"my_custom_analyzer": {
"type": "custom",
"tokenizer": "ngram",
"filter": [
"lowercase",
"asciifolding"
],
"char_filter": [
"html_strip"
],
"min_gram": 2,
"max_gram": 15,
"token_chars": [
"letter",
"digit"
]
}
}
最佳答案
您可能要在groups.title
组之前进行过滤。这意味着您根本不需要顶级查询,也不需要filtered
-level查询。
我没有可用的my_custom_analyzer
,因此我使用了基本的匹配项,但您的主旨是:
GET groups/_search
{
"size": 0,
"aggs": {
"groups": {
"nested": {
"path": "groups"
},
"aggs": {
"titles": {
"filter": {
"match": {
"groups.title": {
"query": "wheel"
}
}
},
"aggs": {
"group_title_terms": {
"terms": {
"field": "groups.title.keyword",
"size": 5
},
"aggs": {
"parents": {
"terms": {
"field": "groups.parent_group_title.keyword",
"size": 3
}
}
}
}
}
}
}
}
}
}
更新:
分析仪存在问题-让我们使用
_analyze
来确定whe
如何被标记化:GET groups/_analyze
{
"text": "whe",
"analyzer": "my_custom_analyzer"
}
屈服
{
"tokens" : [
{
"token" : "w",
"start_offset" : 0,
"end_offset" : 1,
"type" : "word",
"position" : 0
},
{
"token" : "wh",
"start_offset" : 0,
"end_offset" : 2,
"type" : "word",
"position" : 1
},
{
"token" : "h",
"start_offset" : 1,
"end_offset" : 2,
"type" : "word",
"position" : 2
},
{
"token" : "he",
"start_offset" : 1,
"end_offset" : 3,
"type" : "word",
"position" : 3
},
{
"token" : "e",
"start_offset" : 2,
"end_offset" : 3,
"type" : "word",
"position" : 4
}
]
}
我怀疑基于 token
e
,Seats
得到匹配。我的建议是使用
edge_ngram
代替n_gram
,如下所示:PUT groups
{
"settings": {
"analysis": {
"analyzer": {
"my_custom_analyzer": {
"type": "custom",
"tokenizer": "my_tokenizer",
"filter": [
"lowercase",
"asciifolding"
],
"char_filter": [
"html_strip"
]
}
},
"tokenizer": {
"my_tokenizer": {
"type": "edge_ngram",
"min_gram": 2,
"max_gram": 10,
"token_chars": [
"letter",
"digit"
]
}
}
}
},
"mappings": {
"properties": {
"groups": {
"type": "nested",
"properties": {
"group_id": {
"type": "long"
},
"title": {
"type": "text",
"analyzer": "my_custom_analyzer",
"term_vector": "with_positions_offsets",
"fields": {
"keyword": {
"type": "keyword"
}
}
},
"parent_group_id": {
"type": "long"
},
"parent_group_title": {
"type": "text",
"analyzer": "my_custom_analyzer",
"term_vector": "with_positions_offsets",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
}
}
}
应用映射,重新索引,您就可以开始了!
关于elasticsearch - 具有过滤器匹配的Elasticsearch聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62199911/