【问题标题】:ElasticSearch NEST Checking for null valueElasticSearch NEST 检查空值
【发布时间】:2015-08-06 23:21:33
【问题描述】:

我有一个日期时间?字段,如果该字段在未来或它为 NULL,我想返回项目。

NULL检查是问题,ES不存储null值,所以我无法检查。

难道没有什么方法可以检查 .Query 中不存在吗?

我知道我可以 .Filter() 让 ES 返回没有特定字段的项目,但我需要检查 .Query() 中的 NULL 是否不起作用。

我拥有的是:

var results = client.Search<ElasticResult>(s => s
  .Filter(f => f.Missing(ff=>ff.EndTimeUTC) || f.Exists(ff=>ff.EndTimeUTC))         
  .Query(q => q
  .Term(p => p.ShortDescription, "somevalue")
   && ( q.Range(p => p.OnField(f => f.EndTimeUTC).GreaterOrEquals(DateTime.UtcNow)) || 
        q.Term(t => t.EndTimeUTC, null) )   // THIS IS HAVING NO EFFECT
));

我不确定

 .Filter(f => f.Missing("endTimeUTC") || f.Exists("endTimeUTC"))

实际上有什么不同,ShortDescription 查询正在返回所需的文档,它们只是没有 endTimeUTC 字段

【问题讨论】:

    标签: .net elasticsearch nest


    【解决方案1】:

    我猜,你的

     .Filter(f => f.Missing("endTimeUTC") || f.Exists("endTimeUTC"))
    

    没有意义,因为它过滤了missing || exists,所以它什么都不过滤。

    如果您需要按范围搜索并同时显示没有该字段的文档,这就是您所需要的

    POST so/t4/
    {"time": "1900-01-01"}
    POST so/t4/
    {"time": "2100-01-01"}
    POST so/t4
    {}
    
    GET so/t4/_search
    {
      "query": {
        "filtered": {
          "query": {
            "match_all": {}
          },
          "filter": {
            "bool": {
              "should": [
                {
                  "range": {
                    "time": {
                      "gte": "now"
                    }
                  }
                },
                {
                  "missing": {
                    "field": "time"
                  }
                }
              ]
            }
          }
        }
      }
    }
    

    结果:

    {
       "took": 2,
       "timed_out": false,
       "_shards": {
          "total": 5,
          "successful": 5,
          "failed": 0
       },
       "hits": {
          "total": 2,
          "max_score": 1,
          "hits": [
             {
                "_index": "so",
                "_type": "t4",
                "_id": "AU8C4hcnDeuEUel6ntPr",
                "_score": 1,
                "_source": {
                   "time": "2100-01-01"
                }
             },
             {
                "_index": "so",
                "_type": "t4",
                "_id": "AU8C4hr5DeuEUel6ntPs",
                "_score": 1,
                "_source": {}
             }
          ]
       }
    }
    

    should 逻辑使得“数据应该在范围内应该丢失”

    【讨论】:

    【解决方案2】:

    这是我最终得到的 NEST 语法

    var results = client
        .Search<ElasticResult>(s => s
        .Query(q => q
            .Filtered(filtered => filtered
                .Query(t=>t.Term(p => p.ShortDescription, "somevalue"))
                .Filter(ff => ff.
                    Bool(b=> b
                        .Should(n=>n
                            .Range(p => p.OnField(f => f.EndTimeUTC).GreaterOrEquals(DateTime.UtcNow)) 
                            || 
                            n.Missing(m=>m.EndTimeUTC)
                            )
                        )
                    )
                )
            )
        );
    

    【讨论】:

      【解决方案3】:

      与此同时,我还找到了另一个不太优雅的解决方案。 告诉 ES 在字段为空时为其提供默认值:

      var client = new ElasticClient(settings);
      client.Map<ElasticLotResult>(m=>m
          .Properties(props => props
          .Date(s => s
          .Name(p => p.EndTimeUTC)
          .NullValue(DateTime.MinValue)
          ))
      );
      

      然后查询并检查该默认空值:

      .Query(q => q
          .Term(p => p.ShortDescription, "somevalue")
          && (q.Range(p => p.OnField(f => f.EndTimeUTC).GreaterOrEquals(DateTime.UtcNow)) || 
          q.Term(t => t.EndTimeUTC, DateTime.MinValue))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-02
        • 2015-06-05
        • 1970-01-01
        • 1970-01-01
        • 2015-06-26
        • 1970-01-01
        • 2014-03-11
        • 1970-01-01
        相关资源
        最近更新 更多