Как включить несколько полей в QueryParser? - PullRequest
34 голосов
/ 22 января 2009
Dim qp1 As New QueryParser("filename", New StandardAnalyzer())
Dim qp2 As New QueryParser("filetext", New StandardAnalyzer())
.
.

Я использую библиотеку 'Lucene.Net' и у меня следующий вопрос.

Вместо того, чтобы создавать два отдельных объекта QueryParser и использовать их для получения двух объектов Hits, можно ли выполнить поиск по обоим полям, используя один объект QueryParser, чтобы у меня был только один объект Hits, который дает мне общий балл каждого документа?

Ответы [ 4 ]

77 голосов
/ 10 января 2010

Есть 3 способа сделать это.

Первый способ - создать запрос вручную, это то, что QueryParser делает внутри. Это самый эффективный способ сделать это и означает, что вам не нужно анализировать пользовательский ввод, если вы хотите запретить доступ к некоторым из более экзотических функций QueryParser:

IndexReader reader = IndexReader.Open("<lucene dir>");
Searcher searcher = new IndexSearcher(reader);

BooleanQuery booleanQuery = new BooleanQuery();
Query query1 = new TermQuery(new Term("filename", "<text>"));
Query query2 = new TermQuery(new Term("filetext", "<text>"));
booleanQuery.add(query1, BooleanClause.Occur.SHOULD);
booleanQuery.add(query2, BooleanClause.Occur.SHOULD);
// Use BooleanClause.Occur.MUST instead of BooleanClause.Occur.SHOULD
// for AND queries
Hits hits = searcher.Search(booleanQuery);

Второй способ - использовать MultiFieldQueryParser, он ведет себя как QueryParser, предоставляя доступ ко всей его мощности, за исключением того, что он будет искать по нескольким полям.

IndexReader reader = IndexReader.Open("<lucene dir>");
Searcher searcher = new IndexSearcher(reader);

Analyzer analyzer = new StandardAnalyzer();
MultiFieldQueryParser queryParser = new MultiFieldQueryParser(
                                        new string[] {"filename", "filetext"},
                                        analyzer);

Hits hits = searcher.Search(queryParser.parse("<text>"));

Последний способ - использовать специальный синтаксис QueryParser , см. Здесь .

IndexReader reader = IndexReader.Open("<lucene dir>");
Searcher searcher = new IndexSearcher(reader);    

Analyzer analyzer = new StandardAnalyzer();
QueryParser queryParser = new QueryParser("<default field>", analyzer);
// <default field> is the field that QueryParser will search if you don't 
// prefix it with a field.
string special = "filename:" + text + " OR filetext:" + text;

Hits hits = searcher.Search(queryParser.parse(special));

Другой вариант - создать новое поле при индексации содержимого с именем filenameandtext, в которое вы можете поместить содержимое и filename, и filetext, тогда вам придется искать только одно поле.

4 голосов
/ 10 февраля 2009

Просто создайте строку запроса с каждым термином:

"filename:searchText OR filetext:searchText"

Неважно, что вы передаете в качестве начального поля в конструкторе QueryParser. Просто убедитесь, что вы вызываете .Parse () в строке запроса, чтобы вернуть объект Query для выполнения.

Если вы хотите использовать поиск "и":

"+filename:searchText +filetext:searchText"
2 голосов
/ 06 июня 2012

** Вы также можете использовать MultiFieldQueryParser для поиска во всех доступных полях. **

* 1004 например *

Dim queryParser = New MultiFieldQueryParser(Version.LUCENE_29, 
indexReader__1.GetFieldNames(IndexReader.FieldOption.ALL).ToArray(), analyzer)

вот полный пример.

//get index directory
Dim directory As Directory = FSDirectory.Open(New DirectoryInfo(HostingEnvironment.MapPath(VirtualIndexPath)))

//get analyzer
Dim analyzer As Analyzer = New StandardAnalyzer(Version.LUCENE_29)

//get index reader and searcher
Dim indexReader__1 As IndexReader = IndexReader.Open(directory, True)
Dim indexSearch As Searcher = New IndexSearcher(indexReader__1)

//add all possible fileds in multifieldqueryparser using indexreader getFieldNames method
Dim queryParser = New MultiFieldQueryParser(Version.LUCENE_29, indexReader__1.GetFieldNames(IndexReader.FieldOption.ALL).ToArray(), analyzer)
Dim query = queryParser.Parse(Criteria)
Dim resultDocs As TopDocs = Nothing

//perform search
resultDocs = indexSearch.Search(query, indexReader__1.MaxDoc())
Dim hits = resultDocs.scoreDocs

надеюсь, что помощь

1 голос
/ 23 января 2009

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

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

...