Настройка с помощью PostingsSolrHighlighter

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

Настройка, в которой я нуждаюсь, должна удалить ненужные фрагменты, которые не кажутся связанными с искомым пунктом. В настоящее время я использую простой метод: удалите фрагменты с относительным счетом 0,5 или менее. Но я не могу найти способ получить оценки, которые Солр вычисляет для предложений / фрагментов, поэтому я могу отбросить менее желательные.

Могу ли я сказать Solr хранить фрагменты только тогда, когда его оценка больше, чем оценка XYZ, или это может как-то дать мне оценку фрагментов?

Я все еще хочу сохранить порядок (в соответствии с начальной позицией фрагментов в оригинальном документе) результирующих фрагментов.

Благодарю.

1 ответ

Решение

Хорошо, у меня не получилось попросить Solr вернуть фрагменты с оценками или отменить фрагменты с оценкой меньше определенного числа, но я расширил маркер и средство форматирования, а теперь получаю фрагмент с их оценками (абсолютная оценка, вычисленная с помощью solr и относительная оценка)). Ниже приведен код расширения, если он кому-то нужен:

package solrExtension;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.search.Query;
import org.apache.lucene.search.postingshighlight.DefaultPassageFormatter;
import org.apache.lucene.search.postingshighlight.Passage;
import org.apache.lucene.search.postingshighlight.PassageFormatter;
import org.apache.lucene.search.postingshighlight.PostingsHighlighter;
import org.apache.solr.common.params.HighlightParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.highlight.PostingsSolrHighlighter;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.search.DocList;


public class CustomPostingsSolrHighlighter extends PostingsSolrHighlighter {


    protected PostingsHighlighter getHighlighter(SolrQueryRequest req) {
        return new customSolrExtendedPostingsHighlighter(req);
    }

    public class customSolrExtendedPostingsHighlighter extends PostingsSolrHighlighter.SolrExtendedPostingsHighlighter {
        public customSolrExtendedPostingsHighlighter(SolrQueryRequest req) {
            super(req);
        }

        @Override
        protected PassageFormatter getFormatter(String fieldName) {
              String preTag = params.getFieldParam(fieldName, HighlightParams.TAG_PRE, "<em>");
              String postTag = params.getFieldParam(fieldName, HighlightParams.TAG_POST, "</em>");
              String ellipsis = params.getFieldParam(fieldName, HighlightParams.TAG_ELLIPSIS, "... ");
              String encoder = params.getFieldParam(fieldName, HighlightParams.ENCODER, "simple");
              return new CustomPassageFormatter(preTag, postTag, ellipsis, "html".equals(encoder));
        }
    }


    public class CustomPassageFormatter extends DefaultPassageFormatter {
        public CustomPassageFormatter() {
            super();
        }

        public CustomPassageFormatter(String preTag, String postTag,
                String ellipsis, boolean escape) {
            super(preTag, postTag, ellipsis, escape);
        }

        @Override
        public String format(Passage passages[], String content) {
            StringBuilder sb = new StringBuilder();
            int pos = 0;
            double psgTtlScore = 0, maxScore=0, score;
            int psgCounts = 0;
            List<CustomPsg> psgGroups = new ArrayList<CustomPsg>();
            for (Passage passage : passages) {
                // don't add ellipsis if it's the first one, or if it's
                // connected.
                if (passage.getStartOffset() > pos && pos > 0) {
                    score = psgTtlScore / psgCounts;
                    if (score > maxScore)
                        maxScore = score;
                    sb.append("[[").append(score).append("]]");
                    psgGroups.add(new CustomPsg(sb.toString(), score));
                    //sb.append(ellipsis);
                    psgTtlScore = 0;
                    psgCounts = 0;
                    sb = new StringBuilder();
                }
                psgTtlScore += passage.getScore();
                psgCounts++;
                pos = passage.getStartOffset();
                for (int i = 0; i < passage.getNumMatches(); i++) {
                    int start = passage.getMatchStarts()[i];
                    int end = passage.getMatchEnds()[i];
                    // it's possible to have overlapping terms
                    if (start > pos) {
                        append(sb, content, pos, start);
                    }
                    if (end > pos) {
                        sb.append(preTag);
                        append(sb, content, Math.max(pos, start), end);
                        sb.append(postTag);
                        pos = end;
                    }
                }
                sb.append("[").append(passage.getScore()).append("]");
                // it's possible a "term" from the analyzer could span a
                // sentence boundary.
                append(sb, content, pos, Math.max(pos, passage.getEndOffset()));
                pos = passage.getEndOffset();
            }
            sb.append("[[").append(psgTtlScore / psgCounts).append("]]");
            psgGroups.add(new CustomPsg(sb.toString(), psgTtlScore / psgCounts));


            sb = new StringBuilder();
            for (CustomPsg psg : psgGroups) {
                sb.append(psg.psg).append("{{").append(psg.score/maxScore).append("}}").append(ellipsis);
            }
            return sb.toString();
        }

        private class CustomPsg {
            public String psg;
            public double score;
            public CustomPsg(String psg, double score) {
                this.psg = psg;
                this.score = score;
            }
        }
    }

}

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

.....sions and other areas subject to its jurisdiction[22.847776]. [[22.847776]]{{0.954086}}

..... and the Trustee[19.287382]. [[19.287382]]{{0.805409}}

Число в [ ] обозначает оценку отдельного утверждения, число в [[ ]] обозначает среднюю оценку (сумму оценок всех предложений / количество предложений во фрагменте) всего фрагмента (фрагмент может содержать несколько предложений), а число в {{ }} указывает относительный балл сниппета (по сравнению со средним баллом другого сниппета).

Другие вопросы по тегам