我想要实现的是:
看来我不能使用存在查询,因为它不能区分这两种情况。
我应该使用下面的内容吗?
GET /_search
{
"query": {
"bool": {
"must_not": {
"exists": {
"field": "weekly_hours.monday_hours"
}
},
"filter": {
"script": {
"script": {
"source": "doc['weekly_hours.monday_hours'].size != 0",
"lang": "painless"
}
}
}
}
}
}
这样,上述两种情况都会在true
部分返回must_not
,然后在filter
中,第二种情况的大小为0时将被过滤掉。那是对的吗?
有没有更简单的方法?
提前致谢!
更新:
我尝试了上面提到的脚本。我想这个想法可行,但是出现了
Fielddata is not supported on field [weekly_hours.monday_hours] of type [date_range]
异常,如下所示。{
"took": 12,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 4,
"failed": 1,
"failures": [
{
"shard": 3,
"index": "items",
"node": "jRtjvF1mTzG_jPTqkDo2uA",
"reason": {
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"org.elasticsearch.index.mapper.MappedFieldType.fielddataBuilder(MappedFieldType.java:103)",
"org.elasticsearch.index.fielddata.IndexFieldDataService.getForField(IndexFieldDataService.java:111)",
"org.elasticsearch.search.lookup.LeafDocLookup$1.run(LeafDocLookup.java:87)",
"org.elasticsearch.search.lookup.LeafDocLookup$1.run(LeafDocLookup.java:84)",
"java.security.AccessController.doPrivileged(Native Method)",
"org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:84)",
"doc['weekly_hours.monday_hours'].size() != 0",
" ^---- HERE"
],
"script": "doc['weekly_hours.monday_hours'].size() != 0",
"lang": "painless",
"caused_by": {
"type": "illegal_argument_exception",
"reason": "Fielddata is not supported on field [weekly_hours.monday_hours] of type [date_range]"
}
}
}
]
},
"hits": {
"total": 0,
"max_score": null,
"hits": []
}
}
monday_hours
字段的类型为date_range
。这是否意味着我完全不能在该字段上使用脚本?
如果是这样,如何达到我在问题开头所描述的效果?
这里真的需要帮助...
最佳答案
在must_not
上执行weekly_hours.monday_hours
会从技术上过滤掉所有丢失的文档,因此调用doc['weekly_hours.monday_hours'].size() != 0
不会有任何进一步的影响。我说technically
是因为ES不会将所有丢失的值都一样对待-我将在下面详细说明。
更糟糕的是,当前的date_range
字段(> = 7.9)don't support the null_value
parameter在其他字段类型中已经可以实现,而在此类情况下makes one's life easier已经可以实现。
我测试了一些空白字段:
1.
{
"weekly_hours":{
}
}
2.
{
"weekly_hours":{
"monday_hours":{
}
}
}
3.
{
"weekly_hours":{
"monday_hours":{
"gte":null,
"lte":null
}
}
}
最后是一个有效的{
"weekly_hours":{
"monday_hours":{
"gte":"2015-10-31 12:00:00",
"lte":"2015-11-01"
}
}
}
现在,我希望以下查询仅返回4.
,但不会返回,我认为值得filing a bug report:{
"query": {
"bool": {
"must": [
{
"exists": {
"field": "weekly_hours.monday_hours"
}
},
{
"range": {
"weekly_hours.monday_hours": {
"gte": "1970-01-01",
"lte": "2999-12-31"
}
}
},
{
"query_string": {
"query": "_exists_:weekly_hours AND _exists_:weekly_hours.monday_hours AND weekly_hours.monday_hours:[1970-01-01 TO 2999-12-31] AND NOT weekly_hours.monday_hours:[null TO null]"
}
}
]
}
}
}
最后一点:在一周的一天时间内使用
integer_ranges
而不是date_ranges
会更简单吗?现在,鉴于所有这些范围都属于同一个字段类型族,我现在暂时抛弃它们并遵循this neat opening hours approach。
关于elasticsearch - 如何使用查询来区分字段不存在还是字段存在但其值为空数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64520124/