Я хочу настроить поиск в Lucene (фактически Lucene.NET, но я могу при необходимости конвертировать из Java), используя следующую логику:
- Строка поиска: A B C
- Найдите в одном поле индекса все, что соответствует A, B или C. (Запрос:
(field1:A field1:B field1:C)
)
- Для каждого термина, который не совпадает на шаге 2, ищите его во втором поле, сохраняя результаты первого поиска (Запрос:
(+(field1:A) +(field2:B field2:C))
)
- Для каждого термина, не соответствующего шагу 3, найдите третье поле ...
- Продолжайте до тех пор, пока не закончатся поля, или будет поиск, который использовал каждый термин.
В настоящее время мой код может проверять, дает ли данный поиск НЕТ результатов, и объединяет ли И все те, которые действительно дают результаты. Но у меня нет возможности остановить его до того, как он проверит все поля (что излишне ограничивает результаты) - в настоящее время он заканчивается запросом вроде: (+(field1:A field1:B field1:C) +(field3:A field3:B field3:C))
, когда я хочу, чтобы он был (+(field1:A field1:C) +(field3:B))
. Я не могу просто посмотреть на результаты первого поиска и удалить слова из строки поиска, потому что анализатор искажает слова, когда анализирует их для поиска, и у меня нет возможности отменить их, чтобы выяснить, какой из оригинала Поисковым запросам соответствует.
Есть предложения?
Edit:
Хорошо, обычно я предпочитаю описывать свои проблемы в резюме, но я думаю, что некоторая часть этого теряется в процессе, поэтому я буду более конкретным.
Я создаю поисковую систему для сайта, который должен иметь несколько уровней логики поиска. Вот несколько примеров поиска, которые я отследю:
- Наушники
- Наушники Monster
- Наушники White Monster
- Белые наушники Foobar
Индекс содержит документы с семью полями - для этого примера:
- "тип данных" : строка, представляющая, какой тип элемента представляет этот документ (продукт, категория, марка), поэтому мы знаем, как его отобразить
- "бренд" : релевантные бренды (категории имеют несколько брендов, товары и бренды имеют по одному)
- «путь» : путь к данной категории (т. Е. «Аудио наушники-вкладыши» для «Аудио> Наушники> наушники-вкладыши»)
- "ключевые слова" : различные вещи, описывающие продукт, которые никуда не денутся.
Обычно логика для каждого шага поиска выглядит следующим образом:
- Проверьте, есть ли у нас совпадение.
- Если это так, отфильтруйте результаты на основе этого соответствия и продолжите анализ остальных поисковых терминов на следующем шаге.
- Если нет, проанализируйте условия поиска на следующем шаге.
Каждый шаг выглядит примерно так:
- Поиск категории
- Поиск бренда
- Поиск по ключевым словам
Итак, вот как должны воспроизводиться эти три примера поиска:
- Наушники
- Поиск по категории:
+path:headphones +datatype:Category
- Есть совпадения (категория «Наушники»), и в исходном запросе не осталось слов, поэтому мы его возвращаем.
- Наушники-монстры
- Поиск категории: `+ (путь: путь монстра: наушники) + тип данных: категория
- Найдены совпадения для
path:headphones
и datatype:Category
, в результате чего "Monster" не имеет себе равных
- Поиск бренда:
+path:headphones +brand:monster
- Найдены совпадения для
path:headphones
и brand:monster
, и слова из исходного запроса не остались, поэтому мы возвращаем все наушники от Monster.
- Наушники White Monster
- Поиск по категории:
+(path:monster path:headphones path:white) +datatype:Category
- Найдены совпадения для
path:headphones
и datatype:Category
, в результате чего "White" и "Monster" не были сопоставлены
- Поиск бренда:
+path:headphones +(brand:monster +brand:white)
- Найдены совпадения для
path:headphones
и brand:monster
, в результате чего "White" не имеет аналогов
- Ключевые слова для поиска:
+path:headphones +brand:monster +keywords:white
- Есть совпадения, и слова из исходного запроса не остались, поэтому мы их возвращаем.
- Белые наушники Foobar
- Поиск по категории:
+(path:foobar path:headphones path:white) +datatype:Category
- Найдены совпадения для
path:headphones
и datatype:Category
, в результате чего "White" и "Foobar" не были сопоставлены
- Поиск бренда:
+path:headphones +(brand:foobar +brand:white)
- Ничего не найдено, поэтому мы продолжаем.
- Поисковые ключевые слова:
+path:headphones +(keywords:white keywords:foobar)
- Найдены совпадения для
path:headphones
и keywords:white
, в результате чего "Foobar" не имеет аналогов
- ... (продолжить поиск в других полях, включая описание продукта) ...
- Поисковые термины все еще не соответствуют ("Foobar"), возвращают "Ничего не найдено"
У меня двойственная проблема:
- Я не хочу, чтобы совпадения продолжались после того, как все сопоставлено (описания имеют только продукты, поэтому, как только он достигнет этого шага, мы никогда не вернем что-то, что не является продуктом). Я мог бы справиться с этим с помощью GetHitTerms Дениса из здесь , за исключением того, что я в конечном итоге ищу первый совпадающий термин во всех последующих полях, пока все не совпадет (т.е. в примере # 2 у меня будет
+path:headphones +(brand:headphones brand:monster)
).
- Несмотря на мой пример выше, мой фактический поисковый запрос в поле пути выглядит как
+path:headphon +datatype:Taxonomy
, потому что я искажаю его для поиска. Поэтому я не могу взять соответствующий термин и просто удалить его из исходного запроса (потому что "headphon"! = "Наушники").
Надеюсь, это прояснит то, что я ищу.