Lucene.net - Как искать альтернативные индексные ключи или альтернативные словосочетания? - PullRequest
0 голосов
/ 08 декабря 2010

В моем индексе Lucene у меня есть следующие ключи

ID
Полный текст
Пользователь
дата

У меня полнотекстовый поиск работает довольно хорошо, используя следующий метод.

Public Function ReadIndex(ByVal q As String, ByVal page As Integer?) As Domain.Pocos.LuceneResults Implements ILuceneService.ReadIndex
    ''# A timer variable to determine now long the method executes for
    Dim tStart As DateTime = DateTime.Now

    ''# Creates a container that we use to store all of the result ID's
    Dim IDList As List(Of Integer) = New List(Of Integer)

    ''# First we set the initial page number. 
    ''# If it's null, it means it's zero
    If page Is Nothing Then page = 0

    ''# [i] is the variable we use to extract the appropriate (needed)
    ''# documents from the results. Its initial value is the page number
    ''# multiplied by the number of results we want to return (in our
    ''# case 10). The [last] variable is used to stop the while loop at
    ''# the 10th record by simply adding 9 to the [i] variable.
    Dim i = page * 10
    Dim last As Integer = i + 9

    ''# Variables used by Lucene
    Dim reader As IndexReader = IndexReader.Open(luceneDirectory)
    Dim searcher As IndexSearcher = New IndexSearcher(reader)
    Dim query As Query = New TermQuery(New Term("fullText", q.ToLower))

    ''# We're using 10,000 as the maximum number of results to return
    ''# because I have a feeling that we'll never reach that full amount
    ''# anyways.  And if we do, who in their right mind is going to page
    ''# through all of the results?
    Dim topDocs As TopDocs = searcher.Search(query, Nothing, 10000)
    Dim doc As Document = Nothing

    ''# loop through the topDocs and grab the appropriate 10 results based
    ''# on the submitted page number
    While i <= last AndAlso i < topDocs.totalHits
        doc = searcher.Doc(topDocs.scoreDocs(i).doc)
        IDList.Add(doc.[Get]("id"))
        i += 1
    End While

    ''# Self explanitory
    searcher.Close()
    Dim EventList As List(Of Domain.Event) = EventService.QueryEvents().Where(Function(e) (IDList.Contains(e.ID))).ToList()

    Dim tStop As DateTime = DateTime.Now
    Dim LucienResults As New Domain.Pocos.LuceneResults With {.EventList = EventList,
                                                              .ExecuteTime = (tStop - tStart),
                                                              .TotalResults = topDocs.totalHits}

    Return LucienResults
End Function

Теперь у меня проблема с выяснением, как добавить поиск по дате и пользователю в метод.

В основном, если я выполняю поиск по «некоторому событию», результаты отображаются идеально. Однако, если я выполню поиск user:joe или date:12/07/2100, я не получу никаких результатов.

Также, если у меня есть фраза the quick brown fox jumped over the lazy dogs, и я ищу brown fox, я получу получит индексный результат, но если я ищу quick fox, я не смогу получить результаты. По сути, я хотел бы разбить строку на все пробелы и искать каждое слово в отдельности.

Что мне нужно добавить к этому методу, чтобы включить поиск по определенным клавишам и альтернативным словосочетаниям?

1 Ответ

1 голос
/ 08 декабря 2010

Вы в основном ищете "коричневая лиса" и "быстрая лиса" как один токен. Возможно, вы захотите либо разделить пробелы и создать BooleanQuery с несколькими полями TermQuery, либо просто выбросить строку в QueryParser.

Синтаксис "user: joe", который вы описываете, - это то, что QueryParser по умолчанию будет анализировать в новый TermQuery (новый термин ("пользователь", "joe")), что вам и нужно. Ваше текущее решение будет искать один токен «user: joe», который большинство анализаторов разделит на два токена, поэтому вы никогда не получите совпадения с этими анализаторами.

Кроме того, вы не можете сказать своему IndexSearcher.Search остановиться на последнем индексе, который вы будете читать, вместо 10000?

И пока вы не читаете экземпляры документов, используя IndexSearcher.Doc, если вас интересует только одно поле. Используйте FieldCache, который будет хранить кэш в памяти (с помощью устройств чтения сегментов индекса со слабой ссылкой), что позволит вам быстро осуществлять поиск по полям с одним термином.

И, наконец, посмотрите, какой анализатор вы используете. Некоторые специфичны для других языков, некоторые имеют поддержку синонимов или основ, и т. Д. Вещи, с которыми [обычно] облегчает поиск.

...