Поиск между двумя датами с использованием Lucene.Net - PullRequest
3 голосов
/ 22 марта 2012

В моем индексе Lucene.Net у меня есть документы с полем startDate и полем endDate.Оба поля хранят даты в формате yyyyMMdd.Как создать запрос, который будет возвращать совпадения, если сегодняшняя дата находится между этими двумя датами?

startDateFieldValue

Например, если myTargetDate равен 17760604,Я бы хотел получить обратно документ, который имел значение поля startDate 10660101 и значение поля endDate 19990101.

Сценарий состоит в том, что у меня есть база данных Lucene с документами Lucene, которые представляют конкретные строительные площадки.Каждый сайт имеет дату начала строительства и дату окончания строительства.Мои пользователи будут вводить конкретную дату, и я хочу найти все свойства, которые в данный момент находились в стадии строительства.

Примечание. Я работаю с Lucene.Net 1.9, гораздо более старой версией, и моя компания не может выполнить обновление (пока).

Ответы [ 3 ]

6 голосов
/ 27 декабря 2012

Вы можете сделать это, используя Range Query.В частности, вы можете сделать это, используя NumericRangeQuery.Для этого начните с индексации дат с помощью NumericField и добавления их в свой документ, например:

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

Вы можете немного ускорить индексацию, повторно используя 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);

Разделение поиска таким способомгораздо более быстрое предложение, чем использование поиска по тексту, из-за характера индексации числовых полей.Кроме того, ваше разрешение (в данном случае на дневной уровень) может быть изменено, чтобы обеспечить лучший разброс по вашим данным (т. Е. Если вам нужны часы, минуты или секунды, то добавьте их в строку от наиболее значимых до наименее значимых).И наконец, при использовании запроса вы игнорируете этап фильтрации вашего поиска (это обычный запрос, а не фильтр).

1 голос
/ 03 апреля 2012

Я не уверен, что правильно сформулировал свой вопрос.Я хочу выяснить, был ли конкретный элемент активным между начальной и конечной датой.StartDate хранится в одном поле Lucene, а EndDate - в другом.

Вот фрагмент поиска, который я использовал:

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, но боюсь, что не помню ссылку.

Если есть простой / лучший способ написать запрос выше, дайте мне знать.

0 голосов
/ 22 марта 2012

Вы должны использовать RangeQuery .

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

В современной версии вы можете использовать NumericFields / NumericRangeQuery для повышения производительности.

...