ElasticSearch NEST检查空值

时间:2015-08-06 11:30:30

标签: .net elasticsearch nest

我有一个DateTime?字段,如果该字段是将来或我的NULL为NULL,我想返回项目。

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

在.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字段

3 个答案:

答案 0 :(得分:2)

我想,你的

 .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逻辑按字面意思&#34;数据应该在范围内,它应该丢失&#34;

答案 1 :(得分:1)

这是我最后用

的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)
                        )
                    )
                )
            )
        )
    );

答案 2 :(得分:1)

与此同时,我还发现了另一种不那么优雅的解决方案。 告诉ES在字段为null时提供字段的默认值:

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))