Solr: поиск исключает большие фразы - PullRequest
0 голосов
/ 24 июня 2011

Fe У меня есть 3 документа.
1. "собака кошка с мячом"
2. "собака кошка с шарами"
3. "собака кошка, мяч и слон"

Итак.Запрашивая «собака, кошка и мяч», я хочу получить только первые два документа.
Итак.основная идея, которую я хочу включить в результаты только слова, которые я просил.

Буду признателен за любые советы.
спасибо.

Ответы [ 2 ]

1 голос
/ 01 июля 2011

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

  1. Использовать директиву copyfield
  2. Необходимо токенизировать термины
  3. Удалить стоп-слова (в вашем примере)
  4. Сортировать термины в алфавитно-цифровом порядке и сохранитьhash
  5. разверните запрос, чтобы также искать в хэше что-то вроде:

somestring:"dog AND cat AND ball" AND somehash:"dog AND cat AND ball"

Вторая часть поискового запроса будет неявно хешироваться при обработке запроса.

это приведет только к точным совпадениям (с очень нереалистичной вероятностью ложных срабатываний)

PS Вам не нужно хранить термины-векторы.Что приведет к заметно меньшему индексу.

1 голос
/ 25 июня 2011

хорошо, если вы храните свой TermVector (при создании Field, прежде чем добавить Document в индекс, используйте TermVector.YES), это можно сделать, переопределив Collector.Вот простая реализация (которая возвращает только документы без оценок):

private static class MyCollector extends Collector {
    private IndexReader ir;
    private int numberOfTerms;
    private Set<Integer> set = new HashSet<Integer>();

    public MyCollector(IndexReader ir,int numberOfTerms) {
        this.ir = ir;
        this.numberOfTerms = numberOfTerms;

    }

    @Override
    public void setScorer(Scorer scorer) throws IOException {   } //we do not use a scorer in this example

    @Override
    public void setNextReader(IndexReader reader, int docBase) {
        //ignore
    }

    @Override
    public void collect(int doc) throws IOException {
        TermFreqVector vector = ir.getTermFreqVector(doc, CONTENT_FIELD);
                    //CONTENT_FILED is the name of the field you are searching in...
        if (vector != null) {
            if (vector.getTerms().length == numberOfTerms) {
                set.add(doc);
            }
        } else {
            set.add(doc); //well, assume it doesn't happen, because you stored your TermVectors.
        }

    }

    @Override
    public boolean acceptsDocsOutOfOrder() {
        return true;
    }
    public Set<Integer> getSet() { 
        return set;
    }
}; 

сейчас, используйте IndexSearcher#search(Query,Collector)

Идея такова: вы знаете, сколько терминов должно быть в документеесли он должен быть принят, то просто подтвердите его и соберите только те документы, которые соответствуют этому правилу.конечно, это может быть более сложным (ищите конкретный термин в векторе, порядок слов в векторе), но это общая идея.

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

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