我一直在玩ElasticSearch,并在进行聚合时发现了一个问题。
我有两个端点, / A 和 / B 。在第一个我有父母为第二个。因此,B中的一个或多个对象必须属于A中的一个对象。因此,B中的对象具有属性" parentId"使用ElasticSearch生成的父索引。
我想过滤A中的父项属于B的子属性。为了做到这一点,我首先按属性过滤B中的孩子,并获得我以后用来获取父母的独特父ID。
我发送此请求:
POST http://localhost:9200/test/B/_search
{
"query": {
"query_string": {
"default_field": "name",
"query": "derp2*"
}
},
"aggregations": {
"ids": {
"terms": {
"field": "parentId"
}
}
}
}
得到这个回复:
{
"took": 91,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 3,
"max_score": 1,
"hits": [
{
"_index": "test",
"_type": "child",
"_id": "AU_fjH5u40Hx1Kh6rfQG",
"_score": 1,
"_source": {
"parentId": "AU_ffvwM40Hx1Kh6rfQA",
"name": "derp2child2"
}
},
{
"_index": "test",
"_type": "child",
"_id": "AU_fjD_U40Hx1Kh6rfQF",
"_score": 1,
"_source": {
"parentId": "AU_ffvwM40Hx1Kh6rfQA",
"name": "derp2child1"
}
},
{
"_index": "test",
"_type": "child",
"_id": "AU_fjKqf40Hx1Kh6rfQH",
"_score": 1,
"_source": {
"parentId": "AU_ffvwM40Hx1Kh6rfQA",
"name": "derp2child3"
}
}
]
},
"aggregations": {
"ids": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "au_ffvwm40hx1kh6rfqa",
"doc_count": 3
}
]
}
}
}
由于某种原因,过滤后的密钥以小写形式返回,因此无法向ElasticSearch请求父级
GET http://localhost:9200/test/A/au_ffvwm40hx1kh6rfqa
Response:
{
"_index": "test",
"_type": "A",
"_id": "au_ffvwm40hx1kh6rfqa",
"found": false
}
关于为什么会发生这种情况的任何想法?
答案 0 :(得分:3)
命中与聚合结果之间的差异在于聚合适用于创建的术语。他们也将退还条款。点击返回原始来源。
这些条款是如何创建的?基于所选的分析仪,在您的情况下是默认的分析仪,标准分析仪。此分析器所做的一件事就是降低术语的所有字符。就像安德烈提到的那样,你应该将字段parentId配置为not_analyzed。
PUT test
{
"mappings": {
"B": {
"properties": {
"parentId": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
答案 1 :(得分:1)
我来晚了,但是我遇到了同样的问题,并且理解这是由正常化引起的。
如果要防止任何规范化,则必须更改mapping
中的index
,将合计值更改为小写。
您可以通过输入
来检查DevTools console
中的当前映射
GET /A/_mapping
GET /B/_mapping
当您看到索引的结构时,必须查看parentId
字段的设置。
如果您不想更改字段的行为,但又想避免聚合期间的规范化,则可以在parentId
字段中添加一个子字段。
要更改映射,您必须删除索引并使用新的映射重新创建它:
在您的情况下,它看起来像这样(它仅包含parentId字段)
PUT /B/_mapping
{
"properties": {
"parentId": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
然后,您必须在查询中使用子字段:
POST http://localhost:9200/test/B/_search
{
"query": {
"query_string": {
"default_field": "name",
"query": "derp2*"
}
},
"aggregations": {
"ids": {
"terms": {
"field": "parentId.keyword",
"order": {"_key": "desc"}
}
}
}
}