Получить подходящие термины из запроса Lucene - PullRequest
2 голосов
/ 26 октября 2011

С учетом поискового запроса Lucene, например: +(letter:A letter:B letter:C) +(style:Capital), как я могу определить, какая из трех букв соответствует данному документу?Мне все равно, где они совпадают или сколько раз они совпадают, мне просто нужно знать, совпадают ли они.

Намерение состоит в том, чтобы взять начальный запрос («ABC»), удалить термины, которые были успешно сопоставлены (A и B), а затем выполнить дальнейшую обработку оставшейся части (C).

Ответы [ 4 ]

10 голосов
/ 26 октября 2011

Несмотря на то, что образец находится в c #, API Lucene очень похожи (некоторые различия в верхнем / нижнем регистре).Я не думаю, что было бы трудно перевести на Java.

Это использование

List<Term> terms = new List<Term>();    //will be filled with non-matched terms
List<Term> hitTerms = new List<Term>(); //will be filled with matched terms
GetHitTerms(query, searcher,docId, hitTerms,terms);

А вот метод

void GetHitTerms(Query query,IndexSearcher searcher,int docId,List<Term> hitTerms,List<Term>rest)
{
    if (query is TermQuery)
    {
        if (searcher.Explain(query, docId).IsMatch() == true) 
            hitTerms.Add((query as TermQuery).GetTerm());
        else
            rest.Add((query as TermQuery).GetTerm());
        return;
    }

    if (query is BooleanQuery)
    {
        BooleanClause[] clauses = (query as BooleanQuery).GetClauses();
        if (clauses == null) return;

        foreach (BooleanClause bc in clauses)
        {
            GetHitTerms(bc.GetQuery(), searcher, docId,hitTerms,rest);
        }
        return;
    }

    if (query is MultiTermQuery)
    {
        if (!(query is FuzzyQuery)) //FuzzQuery doesn't support SetRewriteMethod
            (query as MultiTermQuery).SetRewriteMethod(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE);

        GetHitTerms(query.Rewrite(searcher.GetIndexReader()), searcher, docId,hitTerms,rest);
    }
}
1 голос
/ 02 августа 2018

Я в основном использовал тот же подход, что и @ LB , но обновил его для использования для новейшей версии Lucene 7.4.0.Примечание: FuzzyQuery теперь поддерживает .setRewriteMethod (поэтому я удалил if).

Я также включил обработку для BoostQuerys и сохранил слова, которые были найдены Lucene в HashSet, чтобы избежать дубликатов вместо Условий.

private void saveHitWordInList(Query query, IndexSearcher indexSearcher,
    int docId, HashSet<String> hitWords) throws IOException {
  if (query instanceof TermQuery)
    if (indexSearcher.explain(query, docId).isMatch())
      hitWords.add(((TermQuery) query).getTerm().toString().split(":")[1]);
  if (query instanceof BooleanQuery) {
    for (BooleanClause clause : (BooleanQuery) query) {
      saveHitWordInList(clause.getQuery(), indexSearcher, docId, hitWords);
    }
  }

  if (query instanceof MultiTermQuery) {
    ((MultiTermQuery) query)
        .setRewriteMethod(MultiTermQuery.SCORING_BOOLEAN_REWRITE);
    saveHitWordInList(query.rewrite(indexSearcher.getIndexReader()),
        indexSearcher, docId, hitWords);
  }

  if (query instanceof BoostQuery)
    saveHitWordInList(((BoostQuery) query).getQuery(), indexSearcher, docId,
        hitWords);
}
1 голос
/ 26 июля 2017

Как ответ @ L.B, вот преобразованный код JAVA, который работает для меня:

void GetHitTerms(Query query,IndexSearcher searcher,int docId,List<Term> hitTerms,List<Term>rest) throws IOException
    {
        if(query instanceof TermQuery )
        {
            if (searcher.explain(query, docId).isMatch())
                hitTerms.add(((TermQuery) query).getTerm());
            else
                rest.add(((TermQuery) query).getTerm());
            return;
        }

            if(query instanceof BooleanQuery )
            {
                for (BooleanClause clause : (BooleanQuery)query) {
                    GetHitTerms(clause.getQuery(), searcher, docId,hitTerms,rest);
            }
            return;
        }

        if (query instanceof MultiTermQuery)
        {
            if (!(query instanceof FuzzyQuery)) //FuzzQuery doesn't support SetRewriteMethod
                ((MultiTermQuery)query).setRewriteMethod(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE);

            GetHitTerms(query.rewrite(searcher.getIndexReader()), searcher, docId,hitTerms,rest);
        }
    }
0 голосов
/ 26 октября 2011

Вы можете использовать кэшированный фильтр для каждого отдельного термина и быстро проверять каждый идентификатор документа по их BitSets .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...