【问题标题】:Search between two dates using Lucene.Net使用 Lucene.Net 在两个日期之间搜索
【发布时间】:2012-03-22 03:31:46
【问题描述】:

在我的 Lucene.Net 索引中,我有包含 startDate 字段和 endDate 字段的文档。这两个字段都以 yyyyMMdd 格式存储日期。如果今天的日期介于这两个日期之间,我如何构建一个返回命中的查询?

startDateFieldValue

例如,如果 myTargetDate 是 17760604,我想要返回一个 startDate 字段值为 10660101 和 endDate 字段值为 19990101 的文档。

场景是我有一个 Lucene 数据库,其中包含代表特定建筑工地的 Lucene 文档。每个站点都有一个 StartConstruction 日期和一个 EndConstruction 日期。我的用户将输入一个特定日期,我想查找该日期当前正在建设的所有属性。

注意:我正在使用 Lucene.Net 1.9,这是一个更旧的版本,我的公司(目前)还不能升级。

【问题讨论】:

  • 例如:+mydatefield:[10660101 TO 19990101] +myotherfield:dthrasher
  • 嗯...我认为这个查询没有意义。让我编辑我的问题以澄清我的意思。

标签: date lucene range lucene.net


【解决方案1】:

您可以使用范围查询来执行此操作。具体来说,您可以使用NumericRangeQuery 执行此操作。为此,首先使用 NumericField 索引您的日期并将它们添加到您的文档中,例如:

var df = new NumericField(Fields.AmendedDate);
df.SetIntValue(int.Parse(itemToIndex.startDate.ToString("yyyyMMdd")));
doc.Add(df);

您可以通过在多个文档see the documentation 中重复使用 NumericField 来加快索引速度。随着您的日期都被很好地索引,您现在可以搜索它了。为此,我们使用 NumericRangeQuery:

var q = NumericRangeQuery.NewIntRange(  Fields.AmendedDate,
                                        int.Parse(SearchFrom.ToString("yyyyMMdd")),
                                        int.Parse(SearchTo.ToString("yyyyMMdd")),
                                        true, true);

此查询随后可用于搜索或连接到现有查询,例如:

masterQuery.Add(q, BooleanClause.Occur.MUST);

由于数字字段索引方式的性质,以这种方式拆分搜索比使用文本词搜索要快得多。此外,您的分辨率(在本例中为日级别)可以更改以更好地分布在您的数据中(即,如果您需要小时、分钟或秒,则将它们从最重要到最不重要的顺序添加到字符串中)。最后一点是,通过使用查询,您会忽略搜索的过滤步骤(这是普通查询,而不是过滤器)。

【讨论】:

【解决方案2】:

我不确定我是否正确地表达了我的问题。我想知道某个特定项目在开始日期和结束日期之间是否处于活动状态。 StartDate 存储在一个 Lucene 字段中,EndDate 存储在另一个字段中。

这是我使用的搜索 sn-p:

var searchableDate = DateTools.DateToString(dateToSearchFor, DateTools.Resolution.DAY);

var lowerRange = new RangeQuery(null, new Term("StartDate", searchableDate), true);
var upperRange = new RangeQuery(new Term("EndDate", searchableDate), null, true);

var activeTodayFilter = new BooleanQuery();
activeTodayFilter.Add(new BooleanClause(lowerRange, BooleanClause.Occur.MUST));
activeTodayFilter.Add(new BooleanClause(upperRange, BooleanClause.Occur.MUST));
return activeTodayFilter;

我在旧的 Lucene 论坛/新闻组中找到了解决方案,但恐怕我不记得链接了。

如果有更简单/更好的方法来编写上面的查询,请告诉我。

【讨论】:

  • 非常感谢 dthrasher.. 过去 1 周我一直在努力寻找满足相同要求的方法.. 这让我很开心:)
【解决方案3】:

您必须使用RangeQuery

RangeQuery rq = new RangeQuery(new Term("date", "10660101"),new Term("date", "19990101") ,true);

在最新版本中,您可以使用 NumericFields/NumericRangeQuery 以获得更好的性能。

【讨论】:

  • 如果我在单个字段中搜索一系列日期,这将起作用。但我需要搜索一个介于开始字段和结束字段之间的日期。 (换句话说,您的示例与我需要的相反。)
  • RangeQuery 表示仍然有效,您可以使用查询日期 +/- 某个步骤。
猜你喜欢
  • 1970-01-01
  • 2012-03-13
  • 2015-07-01
  • 2019-01-27
  • 2022-11-26
  • 1970-01-01
  • 1970-01-01
  • 2013-12-23
  • 1970-01-01
相关资源
最近更新 更多