Lucene.Net如何过滤display_to过期文档且保留无该字段的文档?
问题原因分析
你原有代码的逻辑不符合需求的核心原因是:当前的SHOULD子句仅能匹配到带有display_to字段且值大于等于当前时间的文档,没有处理无display_to字段的文档的兼容逻辑,虽然BooleanFilter存在MUST子句时默认不要求SHOULD子句命中,但该写法逻辑冗余且容易因为minimumNumberShouldMatch配置变化出现异常。
正确的需求逻辑可以简化为:仅排除「存在display_to字段且值小于当前时间」的文档即可,其余文档只要匹配modelId就保留,因此直接用MUST_NOT子句过滤要排除的文档是最简洁的实现。
修改后的代码
BooleanFilter filter = new BooleanFilter(); DateTime date = DateTime.Now; // 原有modelId匹配条件,必须满足 filter.Add(new TermFilter(new Lucene.Net.Index.Term("modelId", modelId.ToString("N"))), Lucene.Net.Search.Occur.MUST); // 新增MUST_NOT子句:排除掉display_to小于等于当前时间的文档,无该字段的文档不会命中此过滤条件,会正常保留 filter.Add(NumericRangeFilter.NewInt64Range("display_to", null, date.ToFileTimeUtc(), false, true), Occur.MUST_NOT);
逻辑说明
NumericRangeFilter.NewInt64Range("display_to", null, date.ToFileTimeUtc(), false, true)表示匹配所有display_to值小于等于当前时间的文档- 把这个范围过滤放到
Occur.MUST_NOT子句中,所有命中这个范围的文档都会被排除 - 没有
display_to字段的文档不会被这个范围过滤匹配到,因此不会被排除,满足永久展示的需求 - 写入索引时
display_to字段要确保是按Int64类型存储的UTC文件时间,和查询时的转换规则保持一致即可。
内容的提问来源于stack exchange,提问作者Thorgeir
相关产品推荐
相关产品推荐

