2016-01-05 3 views
1

Есть ошибка, которую я давно написал с Люценой, ища ответ на этот же вопрос. Но прошло много времени, и даже разработчик анализатора, похоже, не захотел ответить на мои вопросы, поэтому я подумал, что выброшу его на пол, чтобы узнать, сможет ли кто-нибудь объяснить, что здесь происходит.Почему именно этот запрос Lucene не возвращает никаких обращений?

import org.apache.lucene.analysis.Analyzer; 
import org.apache.lucene.analysis.ja.JapaneseAnalyzer; 
import org.apache.lucene.document.Document; 
import org.apache.lucene.document.Field; 
import org.apache.lucene.document.TextField; 
import org.apache.lucene.index.DirectoryReader; 
import org.apache.lucene.index.IndexReader; 
import org.apache.lucene.index.IndexWriter; 
import org.apache.lucene.index.IndexWriterConfig; 
import org.apache.lucene.index.LeafReader; 
import org.apache.lucene.index.LeafReaderContext; 
import org.apache.lucene.index.MultiFields; 
import org.apache.lucene.index.Terms; 
import org.apache.lucene.index.TermsEnum; 
import org.apache.lucene.queryparser.flexible.standard.StandardQueryParser; 
import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler; 
import org.apache.lucene.search.IndexSearcher; 
import org.apache.lucene.search.Query; 
import org.apache.lucene.search.TopDocs; 
import org.apache.lucene.store.Directory; 
import org.apache.lucene.store.RAMDirectory; 
import org.apache.lucene.util.BytesRef; 

public class LuceneMissingTerms { 
    public static void main(String[] args) throws Exception { 
     try (Directory directory = new RAMDirectory()) { 
      Analyzer analyser = new JapaneseAnalyzer(); 

      try (IndexWriter writer = new IndexWriter(directory, new IndexWriterConfig(analyser))) { 
       Document document = new Document(); 
       document.add(new TextField("content", "blah blah commercial blah blah \u79CB\u8449\u539F blah blah", Field.Store.NO)); 
       writer.addDocument(document); 
      } 

      try (IndexReader multiReader = DirectoryReader.open(directory)) { 
       for (LeafReaderContext leaf : multiReader.leaves()) { 
        LeafReader reader = leaf.reader(); 

        Terms terms = MultiFields.getFields(reader).terms("content"); 
        TermsEnum termsEnum = terms.iterator(); 
        BytesRef text; 
        //noinspection NestedAssignment 
        while ((text = termsEnum.next()) != null) { 
         System.out.println("Term in index: " + text.utf8ToString()); 
        } 
       } 

       StandardQueryParser queryParser = new StandardQueryParser(analyser); 
      queryParser.setDefaultOperator(StandardQueryConfigHandler.Operator.AND); 
       String queryString = "\"\u79CB\u8449\u539F\""; 
       // quoted to work around strange behaviour of StandardQueryParser treating this as a boolean query. 
       Query query = queryParser.parse(queryString, "content"); 
       System.out.println("Performing query: " + queryString); 

       TopDocs topDocs = new IndexSearcher(multiReader).search(query, 10); 
       System.out.println("Hits count: " + topDocs.totalHits); 
      } 
     } 
    } 
} 

При запуске этого выход заключается в следующем:

Term in index: blah 
Term in index: commercial 
Term in index: 秋葉原 
Performing query: "秋葉原" 
Hit count: 0 

Итак, мы имеем термин в индексе, где запрос на точно этот термин не находит его. Обычно в этом случае вы не используете один и тот же анализатор при индексировании, как и для запросов, но в приведенном выше примере один и тот же объект анализатора используется для обоих.

Так что я предполагаю, что в анализаторе есть ошибка, и что это связано с контекстом вокруг слова, потому что это единственное, что отличается в двух ситуациях, но у меня нет четкого представления о том, что фактическая проблема или как я буду работать вокруг нее.

С другой стороны, возможно, это ожидаемое поведение? Если это так, то я также могу закрыть свой билет, и конечный пользователь, вероятно, просто немного рассердится, что мы сидели на этой проблеме в течение нескольких лет, прежде чем закрывать этот вопрос.

+0

Почему у вас есть эти дополнительные кавычки вокруг строки запроса и не выполняются с 'queryString =" \ u79CB \ u8449 \ u539F "?? Работает ли это, если вы их оставите? –

ответ

3

Это, конечно, похоже на намеренное поведение, для меня. Я не совсем понимаю все аспекты японского лингвистического анализа, но анализатор Kuromoji имеет функциональность, позволяющую разделить несколько терминов, включает в себя стволовых элементов и анализирует часть речи. Последовательность японских символов, встроенных в кучу текста на английском языке, просто не имеет такого же значения для анализатора, как и сами условия, или как в полном японском полном тексте.

StandardAnalyzer будет отлично работать для конкретного случая, который вы представляете. Если ваш фактический прецедент случайных японских последовательностей в тексте на английском языке, вы, вероятно, должны использовать это. Он предназначен для обработки нескольких языков достаточно хорошо.

Анализатор kuromoji, похоже, хорошо работает на Японский полный текст. Я попытался индексировать некоторый контент из Akihabara (秋葉原) Japanese Wikipedia page, и он работал достаточно хорошо, либо с кавычками в запросе, либо без него. Анализаторы, специфичные для языка, включают в себя множество дополнительных умений, специально предназначенных для этого языка, но взамен они не могут обрабатывать несколько языков, таких как StandardAnalyzer.

Я подозреваю, что это настоящая проблема здесь, тестовый пример немного наивнее. Ваш тестовый документ в основном английский, поэтому EnglishAnalyzer или StandardAnalyzer будут, вероятно, более подходящими для поиска, чем JapaneseAnalyzer.

+0

Вы правы в отношении японского анализатора, генерирующего разные термины, анализатор запросов генерирует эквивалент MultiPhraseQuery для «content:» (秋葉 秋葉原) 原 ". То, что хочет OP, - это новый TermQuery (новый термин («контент», «秋葉原»)), хотя я не знаю, как это сделать с помощью анализатора запросов. – knutwalker

+0

Я догадываюсь, что один бит, который я не получаю, - это то, почему он отбрасывает термины «秋葉» и «原» (ничего себе, я представляю этот комментарий несколько раз, потому что ящик комментариев SO засасывает с помощью IME!), Но только в одном двух ситуаций. Я уверен, что это связано с контекстом ... Мы по умолчанию устанавливаем StandardAnalyzer, и фактический прецедент не является нашим. Другие пользователи используют наше программное обеспечение, у нас нет роскоши быть отстраненным от службы, который может контролировать настройки каждого пользователя.Этот конкретный пользователь решил использовать японскую линию анализа, а затем сообщил об этой ошибке, когда обнаружил ее. – Trejkaz

+0

Тем не менее, контекст отличается _somehow_, но когда я запускаю предложения против отдельных слов через демо-страницу Kuromoji, результаты для этого слова кажутся одинаковыми. – Trejkaz