У меня относительно небольшой индекс, содержащий около 4000 местоположений. Помимо прочего, я использую его для заполнения поля автозаполнения в форме поиска.

Мой индекс содержит документы с полем Location, содержащим такие значения, как

  • Огайо
  • Дейтон, Огайо
  • Дублин, Огайо
  • Колумбус, Огайо

Я хочу иметь возможность вводить «ohi» и отображать все эти результаты, а сейчас ничего не отображается, пока я не наберу слово «ohio» полностью.

Я использую Lucene.NET v2.3.2.1, и соответствующая часть моего кода выглядит следующим образом для настройки моего запроса ...

BooleanQuery keywords = new BooleanQuery();
QueryParser parser = new QueryParser("location", new StandardAnalyzer());
parser.SetAllowLeadingWildcard(true);
keywords.Add(parser.Parse("\"*" + location + "*\""), BooleanClause.Occur.SHOULD);
luceneQuery.Add(keywords, BooleanClause.Occur.MUST);

Короче говоря, я бы хотел, чтобы это работало как предложение LIKE, подобное

SELECT * from Location where Name LIKE '%ohi%'

Могу я сделать это с Lucene?

9
JamieGaines 4 Дек 2009 в 06:59

3 ответа

Лучший ответ

Попробуйте этот запрос:

parser.Parse(query.Keywords.ToLower() + "*")
14
rae1 18 Янв 2013 в 22:21
3
Этот ответ не отражает того, как должен выглядеть окончательный код. Я не понимаю, куда это поставить? Что такое «запрос»? Последний образец был бы отличным.
 – 
irperez
27 Апр 2012 в 01:03
По крайней мере, в Java вам следует обрезать пробелы, так как запрос «Test *» будет компилироваться, а «Test *» - нет.
 – 
bcoughlan
28 Янв 2013 в 17:56
1
@thinkzig: Я знаю, что это старый вопрос, но не могли бы вы отредактировать этот ответ, чтобы показать, как выглядит окончательный код (куда следует добавить эту строку)? Спасибо!
 – 
M4N
18 Мар 2014 в 01:52

Да, это можно сделать. Но ведущий подстановочный знак может привести к медленным запросам. Ознакомьтесь с документацией. Кроме того, если вы индексируете всю строку (например, «Дейтон, Огайо») как отдельный токен, большинство запросов будут преобразованы в запросы с ведущими префиксами. Использование токенизатора, такого как StandardAnalyzer (который, я полагаю, вы уже используете), уменьшит потребность в ведущем подстановочном знаке.

Если вам не нужны ведущие префиксы по соображениям производительности, вы можете попробовать индексацию ngrams. Таким образом, не будет никаких лидирующих запросов с подстановочными знаками. Токенизатор ngram (при условии, что он имеет длину только 4) будет создавать токены для "Dayton Ohio" как "dayt", "ayto", "yton" и так далее.

1
Shashikant Kore 4 Дек 2009 в 09:23
Спасибо за ответ. Меня пока не слишком беспокоят медленные запросы, так как я хотел бы сначала увидеть, как они работают, прежде чем я решу, слишком они медленные или нет. В моем списке местоположений должно оставаться около 4000 документов, поэтому я не слишком беспокоюсь, что он станет больше. Когда вы говорите: «Да, это можно сделать». не могли бы вы уточнить немного подробнее? Я думал, что код, который я показал выше, должен делать то, что я ожидал, но это не так. Есть идеи о том, что я делаю неправильно?
 – 
JamieGaines
4 Дек 2009 в 16:56

Это больше вопрос заполнения вашего индекса частичными словами. Вашему анализатору необходимо вводить частичные ключевые слова в индекс во время анализа (и, надеюсь, взвешивать их ниже, чем полные ключевые слова).

Деревья поиска индекса lucene работают слева направо. Если вы хотите выполнить поиск по середине ключевого слова, вы должны разбить его на части при анализе. проблема в том, что частичные ключевые слова обычно резко увеличивают размер индекса.

Люди обычно используют действительно творческие анализаторы, которые разбивают слова на корневые слова (которые снимают префиксы и суффиксы).

Погрузитесь, чтобы глубже понять Lucene. это хороший материал. :-)

0
Zac Bowling 4 Дек 2009 в 08:54