elasticsearch - 如何使用查询来区分字段不存在还是字段存在但其值为空数组?

标签 elasticsearch

我想要实现的是:

  • 如果字段不存在,则应返回此文档。
  • 当字段存在但其值为空数组时,不应返回此文档。

  • 看来我不能使用存在查询,因为它不能区分这两种情况。
    我应该使用下面的内容吗?
    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/

    相关文章:

    ruby-on-rails - 在Rails中运行查询后如何检查Elasticsearch token ?

    elasticsearch - 将时间戳转换为日期以进行过滤

    elasticsearch - Kibana搜索分析器

    elasticsearch - Logstash文件输入未写入AWS EC2上的Elasticsearch安装

    elasticsearch - 更新要映射到Elasticsearch索引的数据的映射属性

    elasticsearch - Elasticsearch,为什么添加元素总是为空

    elasticsearch - 自定义模式

    elasticsearch - 是否可以通过Elasticsearch中的映射来更新索引中的现有字段?

    elasticsearch - 在geo_shape查询elasticsearch中查找多边形

    elasticsearch - 索引文档后术语被截断(Elasticsearch)