Использование токенизатора lucene ngram для нечеткого совпадения фраз

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

Но я не смог найти токенизатор ngram как часть моей JAR-библиотеки lucene3.4, он устарел и заменен чем-то другим? - в настоящее время я использую стандартный анализатор, где я получаю достойные результаты для точного совпадения терминов.

У меня есть два требования для обработки.

В моем индексе есть документ с фразой «xyz abc pqr», когда я предоставляю запрос «abc xyz» ~ 5, я могу получить результаты, но мое требование состоит в том, чтобы получить результаты для того же документа, даже если у меня есть одно дополнительное слово, например « abc xyz pqr tst" в моем запросе (я понимаю, что оценка совпадения будет немного меньше) - использование дополнительного слова близости во фразе не работает, если я уберу близость и двойные кавычки " " из моего запроса, я получаю ожидаемые результаты (но там Я получаю много ложных срабатываний, таких как документы, содержащие только xyz, только abc и т. д.)

В том же приведенном выше примере, если кто-то ошибся в запросе «abc xxz», я все равно хочу получить результаты для того же документа.

Я хочу попробовать ngram, но не уверен, что он будет работать должным образом.

Есть предположения ?


person Rushik    schedule 21.02.2012    source источник


Ответы (1)


Попробуйте использовать BooleanQuery и FuzzyQuery, например:

    public void fuzzysearch(String querystr) throws Exception{
        querystr=querystr.toLowerCase();

        System.out.println("\n\n-------- Start fuzzysearch -------- ");

        // 3. search
        int hitsPerPage = 10;
        TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true);
        IndexReader reader = IndexReader.open(index);

        IndexSearcher searcher = new IndexSearcher(reader);
        BooleanQuery bq = new BooleanQuery();

        String[] searchWords = querystr.split(" ") ;
        int id=0;
        for(String word: searchWords ){
            Query query = new FuzzyQuery(new Term(NAME,word));
            if(id==0){
                bq.add(query, BooleanClause.Occur.MUST);
            }else{
                bq.add(query, BooleanClause.Occur.SHOULD);
            }
          id++;
        }
        System.out.println("query ==> " + bq.toString());
        searcher.search(bq, collector );
        parseResults(  searcher, collector  ) ;
        searcher.close();
    }

public void parseResults(IndexSearcher searcher, TopScoreDocCollector collector  ) throws  Exception {
ScoreDoc[] hits = collector.topDocs().scoreDocs;

    // 4. display results
    System.out.println("Found " + hits.length + " hits.");
    for(int i=0;i<hits.length;++i) {
      int docId = hits[i].doc;
      Document d = searcher.doc(docId);
      System.out.println((i + 1) + ". " + d.get(NAME));
    }

}
person John Li    schedule 29.02.2012
comment
Спасибо Джон, я попробую это и дам вам знать. - person Rushik; 29.02.2012