Lucene и специальные персонажи - PullRequest
9 голосов
/ 29 апреля 2010

Я использую Lucene.Net 2.0 для индексации некоторых полей из таблицы базы данных. Одним из полей является поле «Имя», которое допускает специальные символы. Когда я выполняю поиск, он не находит мой документ, который содержит термин со специальными символами.

Я индексирую свое поле как таковое:

Directory DALDirectory = FSDirectory.GetDirectory(@"C:\Indexes\Name", false);
Analyzer analyzer = new StandardAnalyzer();
IndexWriter indexWriter = new IndexWriter(DALDirectory, analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED);

Document doc = new Document();
doc.Add(new Field("Name", "Test (Test)", Field.Store.YES, Field.Index.TOKENIZED));
indexWriter.AddDocument(doc);

indexWriter.Optimize();
indexWriter.Close();

И я ищу, делая следующее:

value = value.Trim().ToLower();
value = QueryParser.Escape(value);

Query searchQuery = new TermQuery(new Term(field, value));
Searcher searcher = new IndexSearcher(DALDirectory);

TopDocCollector collector = new TopDocCollector(searcher.MaxDoc());
searcher.Search(searchQuery, collector);
ScoreDoc[] hits = collector.TopDocs().scoreDocs;

Если я выполняю поиск поля как «Имя» и значения как «Тест», он находит документ. Если я выполняю тот же поиск, что и «Имя», а значение «Тест (Тест)», то документ не находит.

Еще более странно, если я удаляю строку QueryParser.Escape, выполняю поиск GUID (который, конечно, содержит дефисы), он находит документы, где совпадает значение GUID, но выполняет тот же поиск со значением, что и 'Test (Тест) 'по-прежнему не дает результатов.

Я не уверен, что я делаю неправильно. Я использую метод QueryParser.Escape для экранирования специальных символов, сохраняю поле и выполняю поиск по примерам Lucene.Net.

Есть мысли?

Ответы [ 2 ]

5 голосов
/ 29 апреля 2010

StandardAnalyzer удаляет специальные символы во время индексации. Вы можете передать список явных стоп-слов (исключая те, которые вам нужны).

3 голосов
/ 29 апреля 2010

Во время индексации вы токенизировали поле. Итак, ваш входной String создает два токена "test" и "test". Для поиска вы создаете запрос вручную, т.е. используете TermQuery вместо QueryParser, который бы токенизировал поле.

Для полного соответствия вам нужно проиндексировать поле UN_TOKENIZED. Здесь входная строка берется как один токен. Единственный токен создал «Test (Тест)». В этом случае ваш текущий код поиска будет работать. Вы должны внимательно следить за регистром входной строки, чтобы убедиться, что при индексации текста в нижнем регистре вы должны делать то же самое при поиске.

Обычно рекомендуется использовать один и тот же анализатор во время индексации и поиска. Вы можете использовать KeywordAnalyer для генерации одного токена из входной строки.

...