Оценка запросов Lucene на основе нескольких сопоставленных столбцов - PullRequest
0 голосов
/ 26 января 2012

Я использую Lucene для поиска контактов напрямую с общей контактной информацией для базы данных людей, такой как имя, фамилия, номер телефона, адрес и т. Д. Этот вопрос относится конкретно к поиску по имени и фамилии.Вот как я индексирую имена.

document.add(new Field("firstName", contact.getFirstName(), Field.Store.NO, Field.Index.NOT_ANALYZED));
document.add(new Field("lastName", contact.getLastName(), Field.Store.NO, Field.Index.NOT_ANALYZED));

Я ищу индекс так:

IndexReader indexReader = IndexReader.open(FSDirectory.open(directory));
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
int hitsPerPage = indexSearcher.maxDoc();
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_35);
String[] fields = {"id", "firstName", "lastName", "phoneNumber", "email", "address", "website"};

BooleanQuery booleanQuery = new BooleanQuery();
String[] terms = queryString.split(" ");

for(String term : terms) {
    for(String field : fields) {
        booleanQuery.add(new FuzzyQuery(new Term(field, term)), BooleanClause.Occur.SHOULD);
    }
}

TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true);
indexSearcher.search(booleanQuery, collector);
ScoreDoc[] hits = collector.topDocs().scoreDocs;

Причина, по которой я использую логический запрос, а не MultiFieldQuery, заключается в том, чтоэто позволяет мне получать результаты, когда поле не является точным.По сути, я разделяю строку запроса по пробелам, а затем добавляю термины для каждого из этих ключевых слов в каждое поле индекса.Я новичок в Lucene, так что я действительно понятия не имею, является ли это оптимальным способом сделать это, но пока он работает хорошо для меня.

Единственный сбой, который у меня возникает, это то, что при поиске пополное имя не возвращает результаты в правильном порядке.

Индекс имеет 2 записи, Джон Доу и Джон Смит.

Когда я ищу Джона Доу, мои результаты будут выглядеть так: 1)Джон Смит 2) Джон Доу

Если я наберу Джон Смит, он перевернется и покажет Джона Доу.Почему он не возвращает точное совпадение в качестве первого результата?

Ответы [ 2 ]

0 голосов
/ 06 февраля 2012

Использование логических запросов и цикла for оказалось правильным способом поиска по индексу в моей ситуации.Результаты были отменены из-за того, как я анализировал и отображал их на стороне клиента, поэтому это была совершенно не связанная проблема.

0 голосов
/ 26 января 2012

Если вы собираетесь искать все термины во всех полях, почему бы не проиндексировать весь текст как часть другого поля?И тогда вы можете выполнить запрос типа

/*
\\\\ is for escaping "
*/
String searchCriteria = "all:\\\\"John Doe\\\\"^3 OR all:(John Doe)"; 
IndexSearcher is = new IndexSearcher(indexDirectory);
Analyzer analyzer = new StandardAnalyzer();
QueryParser parser = new QueryParser("all", analyzer);
Query query = parser.parse(searchCriteria);
TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true);
indexSearcher.search(query, collector);
ScoreDoc[] hits = collector.topDocs().scoreDocs;

Однако, если вы хотите продолжить работу с вашим текущим дизайном, вы можете попробовать http://lucene.apache.org/java/3_5_0/api/all/org/apache/lucene/search/IndexSearcher.html#explain(org.apache.lucene.search.Query, int), чтобы узнать, почему документ оценивается вышечем другие.

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