Индексация и поиск по дате в Lucene - PullRequest
10 голосов
/ 31 марта 2011

Я пытался индексировать дату с помощью метода DateTools.dateToString().Он работает как для индексации, так и для поиска.

Но мои уже проиндексированные данные, на которые есть некоторые ссылки, таковы, что они проиндексировали Date как новый Date().getTime().

Так что мойпроблема заключается в том, как выполнить RangeSearch Query на этих данных ...

Любое решение этого вопроса *

Заранее спасибо.

Ответы [ 2 ]

18 голосов
/ 31 марта 2011

Вам необходимо использовать TermRangeQuery в поле даты. Это поле всегда должно быть проиндексировано с DateTools.dateToString(), чтобы оно работало правильно. Вот полный пример индексации и поиска в диапазоне дат с помощью Lucene 3.0:

public class LuceneDateRange {
    public static void main(String[] args) throws Exception {
        // setup Lucene to use an in-memory index
        Directory directory = new RAMDirectory();
        Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);
        MaxFieldLength mlf = MaxFieldLength.UNLIMITED;
        IndexWriter writer = new IndexWriter(directory, analyzer, true, mlf);

        // use the current time as the base of dates for this example
        long baseTime = System.currentTimeMillis();

        // index 10 documents with 1 second between dates
        for (int i = 0; i < 10; i++) {
            Document doc = new Document();
            String id = String.valueOf(i);
            String date = buildDate(baseTime + i * 1000);
            doc.add(new Field("id", id, Store.YES, Index.NOT_ANALYZED));
            doc.add(new Field("date", date, Store.YES, Index.NOT_ANALYZED));
            writer.addDocument(doc);
        }
        writer.close();

        // search for documents from 5 to 8 seconds after base, inclusive
        IndexSearcher searcher = new IndexSearcher(directory);
        String lowerDate = buildDate(baseTime + 5000);
        String upperDate = buildDate(baseTime + 8000);
        boolean includeLower = true;
        boolean includeUpper = true;
        TermRangeQuery query = new TermRangeQuery("date",
                lowerDate, upperDate, includeLower, includeUpper);

        // display search results
        TopDocs topDocs = searcher.search(query, 10);
        for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
            Document doc = searcher.doc(scoreDoc.doc);
            System.out.println(doc);
        }
    }

    public static String buildDate(long time) {
        return DateTools.dateToString(new Date(time), Resolution.SECOND);
    }
}
3 голосов
/ 15 мая 2011

Вы получите гораздо лучшую производительность поиска, если будете использовать NumericField для своей даты, а затем NumericRangeFilter / Query для поиска по диапазону.

Вам просто нужно закодировать дату как long или int. Одним простым способом является вызов метода .getTime () для вашей даты, но это может быть гораздо большее разрешение (миллисекунды), чем вам нужно. Если вам нужно только до дня, вы можете закодировать его как целое число ГГГГММДД.

Затем, во время поиска, выполните то же преобразование в начале / конце Даты и запустите NumericRangeQuery / Filter.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...