ElasticSearch NEST 检查空值
ElasticSearch NEST Checking for null value
我有日期时间?字段,我想要 return 个项目,如果该字段在未来或者它为 NULL。
NULL 检查是问题所在,ES 不存储空值,所以无法检查。
有没有办法检查 .Query 中是否存在 none?
我知道我可以 .Filter() 将 ES 获取到 return 没有特定字段的项目,但我需要检查 .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 查询 return 编辑,它们只是没有 endTimeUTC 字段
我猜,你的
.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
逻辑从字面上看 "data should be in range or it should be missing"
这是我最终得到的 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)
)
)
)
)
)
);
与此同时,我还找到了另一个不太优雅的解决方案。
告诉 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))
我有日期时间?字段,我想要 return 个项目,如果该字段在未来或者它为 NULL。
NULL 检查是问题所在,ES 不存储空值,所以无法检查。
有没有办法检查 .Query 中是否存在 none?
我知道我可以 .Filter() 将 ES 获取到 return 没有特定字段的项目,但我需要检查 .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 查询 return 编辑,它们只是没有 endTimeUTC 字段
我猜,你的
.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
逻辑从字面上看 "data should be in range or it should be missing"
这是我最终得到的 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)
)
)
)
)
)
);
与此同时,我还找到了另一个不太优雅的解决方案。 告诉 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))