如何使用NEST构建ElasticSearch空值字段查询?
问题描述
需要构建ElasticSearch查询,匹配指定字段值为null的文档,但ElasticSearch会忽略包含null值的Term查询条件。尝试的NEST代码如下:
.Query(q => q .Bool(b => b .Must( sh => sh.MatchPhrasePrefix(w => w.Field("Vrvirksomhed.virksomhedMetadata.nyesteNavn.navn").Query($"{criteria.SearchName}")), sh => sh.MatchPhrasePrefix(w => w.Field("Vrvirksomhed.virksomhedMetadata.nyesteBeliggenhedsadresse.vejnavn").Query($"{criteria.StreetName}")), sh => sh.Match(w => w.Field("Vrvirksomhed.virksomhedMetadata.nyesteBeliggenhedsadresse.husnummerFra").Query($"{criteria.StreetbuildingIdentifier}")), sh => sh.Match(w => w.Field("Vrvirksomhed.virksomhedMetadata.nyesteBeliggenhedsadresse.postnummer").Query($"{criteria.ZipCode}")), sh => sh.Match(m => m.Field("Vrvirksomhed.cvrNummer").Query(criteria.CVRNumber)), sh => sh.Match(m => m.Field("Vrvirksomhed.penheder.pNummer").Query(criteria.PNumber)) ) .Filter(f => f.Term("Vrvirksomhed.virksomhedMetadata.nyesteBeliggenhedsadresse.periode.gyldigTil", null)) ) )
但查询会忽略gyldigTil字段的条件,示例文档中该字段既有具体值也有null。
解决方案
Elasticsearch中,字段值为null、空数组或不存在的字段不会被加入索引,因此Term查询无法匹配这类情况。要匹配gyldigTil为null的文档,需使用**MustNot + Exists**组合查询,这是新版本Elasticsearch推荐的方式(旧版的Missing查询已被替代)。
修改后的NEST代码
将原有的Term过滤器替换为MustNot包裹的Exists查询,代码如下:
.Query(q => q .Bool(b => b .Must( sh => sh.MatchPhrasePrefix(w => w.Field("Vrvirksomhed.virksomhedMetadata.nyesteNavn.navn").Query($"{criteria.SearchName}")), sh => sh.MatchPhrasePrefix(w => w.Field("Vrvirksomhed.virksomhedMetadata.nyesteBeliggenhedsadresse.vejnavn").Query($"{criteria.StreetName}")), sh => sh.Match(w => w.Field("Vrvirksomhed.virksomhedMetadata.nyesteBeliggenhedsadresse.husnummerFra").Query($"{criteria.StreetbuildingIdentifier}")), sh => sh.Match(w => w.Field("Vrvirksomhed.virksomhedMetadata.nyesteBeliggenhedsadresse.postnummer").Query($"{criteria.ZipCode}")), sh => sh.Match(m => m.Field("Vrvirksomhed.cvrNummer").Query(criteria.CVRNumber)), sh => sh.Match(m => m.Field("Vrvirksomhed.penheder.pNummer").Query(criteria.PNumber)) ) .Filter(f => f.Bool(bf => bf.MustNot(mn => mn.Exists(e => e.Field("Vrvirksomhed.virksomhedMetadata.nyesteBeliggenhedsadresse.periode.gyldigTil"))))) ) )
补充说明
上述查询会匹配两种情况:
gyldigTil字段存在但值为nullgyldigTil字段完全不存在
如果需要仅匹配字段存在但值为null的场景,可以结合Exists和Term的否定,但大多数业务场景下MustNot + Exists已足够满足需求。
内容的提问来源于stack exchange,提问作者Axel Andersen
相关产品推荐
相关产品推荐

