Использование лексена Ngram Tokenizer для совпадения нечетких фраз - PullRequest
2 голосов
/ 21 февраля 2012

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

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

У меня ниже двух требований к ним.

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

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

Я хочу попробовать ngram, но не уверен, что он будет работать так, как ожидалось.

Есть мысли?

1 Ответ

4 голосов
/ 29 февраля 2012

Попробуйте использовать 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));
    }

}
...