2013-08-14 2 views
2

Позвольте мне предисловие, сказав, что я не использую Lucene очень распространенным способом и объясняю, как мой вопрос имеет смысл. Я использую Lucene для поиска в структурированных записях. То есть каждый документ, который индексируется, представляет собой набор полей с короткими значениями из заданного набора. Каждое поле анализируется и сохраняется, при этом анализ обычно составляет не более 3 и в большинстве случаев всего 1 нормализованный токен. Например, представьте файлы для каждого из которых мы сохраняем два поля: путь к файлу и рейтинг пользователя в 1-5. Путь символизируется PathHierarchyTokenizer, и рейтинг просто сохраняется как есть. Так что, если у нас есть документ, какКак я могу попросить Луцен сделать простой, плоский подсчет?

path: "https://stackoverflow.com/a/b/file.txt" 
rating: 3 

Этот документ будет иметь для своего поля пути лексемы «/ а», «/ а/б» и «/a/b/file.ext», а также для рейтинг маркера «3».

Я хочу заручиться этим документом по запросу типа «путь:/путь:/a/b путь: /a/b/different.txt рейтинг: 1» и получить значение 2 - количество терминов что соответствует.

Мое понимание и наблюдение заключается в том, что оценка документа зависит от разных терминов и многих документов со многими полями, и я определенно не получаю простых целочисленных оценок.

Есть ли способ сделать документы Lucene в соответствии с изложенным способом? Запросы, которые запускаются против индекса, не генерируются пользователями, но создаются системой и имеют дополнительный фильтр, что означает, что у всех из них есть фиксированная форма нескольких TermQuery, соединенных в BooleanQuery, ничем не отличающихся от нечетких текстовых запросов. В настоящее время у меня нет возможности заменить Lucene чем-то другим, но предложения могут быть полезны для будущей разработки.

ответ

1

Я сомневаюсь, что есть что-то готовое к использованию, поэтому, скорее всего, вам понадобится реализовать свой собственный бомбардир и использовать его при поиске. Для сложных случаев вам может понадобиться play around with queries, но для простого случая, такого как ваш, этого должно быть достаточно, чтобы overwrite DefaultSimilarity установил tf фактор для частоты raw (количество указанных терминов в документе) и все остальные компоненты в 1. Что-то вроде этого:

public class MySimilarity extends DefaultSimilarity { 

    @Override 
    public float computeNorm(String field, FieldInvertState state) { 
     return 1; 
    } 

    @Override 
    public float queryNorm(float sumOfSquaredWeights) { 
     return 1; 
    } 

    @Override 
    public float tf(float freq) { 
     return freq; 
    } 

    @Override 
    public float idf(int docFreq, int numDocs) { 
     return 1; 
    } 

    @Override 
    public float coord(int overlap, int maxOverlap) { 
     return 1; 
    } 

} 

(Обратите внимание, что tf() это единственный метод, который возвращает что-то другое, чем 1)

и праведники set similarity на IndexSearcher.

Смежные вопросы