绊脚石乃是进身之阶。

关于Elasticsearch的嵌套查询问题,为何返回的子集中含有不符合过滤条件的?

Elasticsearch | 作者 HelloWorld | 发布于2016年08月30日 | 阅读数:9893

新建了一个如下的索引,其中SCORE字段为嵌套类型,结构如下:
{
"mo": {
"mappings": {
"T_TEST_EMP": {
"properties": {
"EMPAGE": {
"type": "long"
},
"EMPID": {
"type": "long"
},
"EMPNAME": {
"type": "string"
},
"EMPSEX": {
"type": "long"
},
"SCORE": {
"type": "nested",
"include_in_parent": true,
"properties": {
"EMPID": {
"type": "long"
},
"MONTH": {
"type": "date",
"format": "dateOptionalTime"
},
"SCORE": {
"type": "double"
},
"SCOREID": {
"type": "long"
}
}
}
}
}
}
}
}

索引里面的数据:
{
"took": 4,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 4,
"max_score": 1,
"hits": [
{
"_index": "mo",
"_type": "T_TEST_EMP",
"_id": "4",
"_score": 1,
"_source": {
"EMPID": 4,
"EMPNAME": "赵六",
"EMPSEX": 1,
"EMPAGE": 30
}
},
{
"_index": "mo",
"_type": "T_TEST_EMP",
"_id": "1",
"_score": 1,
"_source": {
"EMPID": 1,
"EMPNAME": "张三",
"EMPSEX": 0,
"EMPAGE": 15,
"SCORE": [
{
"EMPID": 1,
"SCOREID": 1,
"SCORE": 78,
"MONTH": "2015-12-31T16:00:00.000Z"
},
{
"EMPID": 1,
"SCOREID": 2,
"SCORE": 75,
"MONTH": "2016-01-01T16:00:00.000Z"
},
{
"EMPID": 1,
"SCOREID": 3,
"SCORE": 90,
"MONTH": "2016-01-02T16:00:00.000Z"
}
]
}
},
{
"_index": "mo",
"_type": "T_TEST_EMP",
"_id": "2",
"_score": 1,
"_source": {
"EMPID": 2,
"EMPNAME": "李四",
"EMPSEX": 0,
"EMPAGE": 18,
"SCORE": [
{
"EMPID": 2,
"SCOREID": 4,
"SCORE": 88,
"MONTH": "2015-12-31T16:00:00.000Z"
},
{
"EMPID": 2,
"SCOREID": 5,
"SCORE": 89,
"MONTH": "2016-01-01T16:00:00.000Z"
},
{
"EMPID": 2,
"SCOREID": 6,
"SCORE": 96,
"MONTH": "2016-01-02T16:00:00.000Z"
}
]
}
},
{
"_index": "mo",
"_type": "T_TEST_EMP",
"_id": "3",
"_score": 1,
"_source": {
"EMPID": 3,
"EMPNAME": "王五",
"EMPSEX": 0,
"EMPAGE": 8,
"SCORE": [
{
"EMPID": 3,
"SCOREID": 7,
"SCORE": 60,
"MONTH": "2015-12-31T16:00:00.000Z"
},
{
"EMPID": 3,
"SCOREID": 8,
"SCORE": 63,
"MONTH": "2016-01-01T16:00:00.000Z"
},
{
"EMPID": 3,
"SCOREID": 9,
"SCORE": 64,
"MONTH": "2016-01-02T16:00:00.000Z"
}
]
}
}
]
}
}

现在我希望对嵌套的子集SCORE进行过滤,查询95分以上的记录,但是不知道为什么,只能过滤到主记录,主记录中包含的其他不在95分以上的子记录也被查询出来了..
GET mo/T_TEST_EMP/_search
{
"query": {
"bool": {
"must": [
{
"range": {
"SCORE.SCORE": {
"gte": 95
}
}
}
]
}
}
}
查询结果:
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "mo",
"_type": "T_TEST_EMP",
"_id": "2",
"_score": 1,
"_source": {
"EMPID": 2,
"EMPNAME": "李四",
"EMPSEX": 0,
"EMPAGE": 18,
"SCORE": [
{
"EMPID": 2,
"SCOREID": 4,
"SCORE": 88,
"MONTH": "2015-12-31T16:00:00.000Z"
},
{
"EMPID": 2,
"SCOREID": 5,
"SCORE": 89,
"MONTH": "2016-01-01T16:00:00.000Z"
},
{
"EMPID": 2,
"SCOREID": 6,
"SCORE": 96,
"MONTH": "2016-01-02T16:00:00.000Z"
}
]
}
}
]
}
}
其中,如下两条记录为什么也会被查出来呢????????????
{
"EMPID": 2,
"SCOREID": 4,
"SCORE": 88,
"MONTH": "2015-12-31T16:00:00.000Z"
},
{
"EMPID": 2,
"SCOREID": 5,
"SCORE": 89,
"MONTH": "2016-01-01T16:00:00.000Z"
}
已邀请:

Jea - 一只猿

赞同来自: liushui00001

在es中有一个特殊的字段不在标注里面, _source, 就是你在存储数据的时候给es的数据
如果在setting时, 没有设置_source:false
那么, 在你查询的时候, 会将你put到es时候的数据原样返回给你, 这就是为什么你得到的是包含有其他数据的_srouce, 如果你需要部分source那么提供_srouce字段在查询时, 会返回给你你需要的source而不是全量返回
 
关于索引的用法, 我一直认为索引是为了解决关键问题的, 不能像数据库一样滥用, so!!! 只存储想要的数据, 得到返回的id, 再去数据库里取得相关的详细数据

liushui00001 - 软件工程师

赞同来自: zengercool

"_source": {  
    "enabled": true 
  }
表示将所有field作为一个整体一起存储和查询出来;

 "store": false   表示 设置sore:fasle的field单独存储,_source中不包含该field;

可以实现 取 部分field,而不是 取所有field  ; 因此 上面的设置 解决 的是  取部分 field 数据, 而不是 所有field 中的部分数据!!!!!

上面 的问题,其实 是   获取 所有field  的 满足条件  的部分 数据; 也是我项目中遇到 的问题;

以上 是我对_source和store的理解,如有不对之处,还请指正

martindu - 搜披露创始人

赞同来自:

.的嵌套会把匹配查询条件的数组都返回。如果你要实现只返回符合条件的子记录的话,或者在后端接收数据后处理(每个hit肯定至少有一个子记录匹配你的查询条件),或者将索引改成父子类。

liushui00001 - 软件工程师

赞同来自:

我也碰到这个问题了。至于 上面的答复:
嵌套会把匹配查询条件的数组都返回。如果你要实现只返回符合条件的子记录的话,或者在后端接收数据后处理(每个hit肯定至少有一个子记录匹配你的查询条件),或者将索引改成父子类。

我一点都没有看懂!!!!!!!!不明白martindu 说的是啥意思!!!!!!!
 

要回复问题请先登录注册