Эта статья является частью нашего академического курса под названием Apache Lucene Fundamentals .
В этом курсе вы познакомитесь с Lucene. Вы поймете, почему такая библиотека важна, а затем узнаете, как работает поиск в Lucene. Кроме того, вы узнаете, как интегрировать Lucene Search в ваши собственные приложения, чтобы обеспечить надежные возможности поиска. Проверьте это здесь !
Содержание
1. Введение
Java Lucene предоставляет довольно мощный язык запросов для выполнения операций поиска в большом количестве данных.
Запрос разбит на термины и операторы. Есть три типа терминов: отдельные термины , фразы и подзапросы . Один термин — это одно слово, такое как «тест» или «привет». Фраза — это группа слов, заключенная в двойные кавычки, такие как «привет Долли». Подзапрос — это запрос, заключенный в круглые скобки, например, «(привет привет)».
Lucene поддерживает поля данных. При выполнении поиска вы можете либо указать поле, либо использовать поле по умолчанию. Имена полей зависят от индексированных данных, а поле по умолчанию определяется текущими настройками.
2. Разбор строки запроса
Задача анализатора запросов — преобразовать строку запроса, отправленную пользователем, в объекты запроса.
Запрос используется анализатором запросов, который анализирует его содержимое. Вот пример:
1
2
3
4
5
6
|
{ "query_string" : { "default_field" : "content" , "query" : "this AND that OR thus" } } |
Параметры верхнего уровня query_string
включают в себя:
Когда генерируется многоточечный запрос, можно контролировать, как он переписывается, используя параметр rewrite
.
2.1. Правила QueryParser
Предположим, вы ищете в Интернете страницы, содержащие слова java и net, но не слово dot. Что если поисковые системы заставят вас напечатать что-то вроде следующего для этого простого запроса?
1
2
3
4
|
BooleanQuery query = new BooleanQuery(); query.add( new TermQuery( new Term( "contents" , "java" )), true , false ); query.add( new TermQuery( new Term( "contents" , "net" )), true , false ); query.add( new TermQuery( new Term( "contents" , "dot" )), false , true ); |
Это было бы настоящим тормозом. К счастью, Google, Nutch и другие поисковые системы более дружественны, позволяя вам вводить что-то более лаконичное: java AND net NOT dot
Сначала мы посмотрим, что нужно для использования QueryParser в приложении.
2.2. Использование QueryParser
Использование QueryParser
довольно просто. Необходимы три вещи: выражение, имя поля по умолчанию, которое будет использоваться для неквалифицированных полей в выражении, и анализатор для частей выражения. Спецификаторы выбора полей обсуждаются в разделе синтаксиса запроса. Анализ, специфичный для анализа запросов, описан в разделе «Анализ паралича». Теперь давайте разберем выражение:
1
2
|
String humanQuery = getHumanQuery(); Query query = QueryParser.parse(humanQuery, "contents" , new StandardAnalyzer()); |
После того, как вы получили объект Query
, поиск выполняется так же, как если бы запрос был создан непосредственно через API. Вот полный метод для поиска существующего индекса с помощью введенной пользователем строки запроса и отображения результатов на консоли:
01
02
03
04
05
06
07
08
09
10
11
12
|
public static void search(File indexDir, String q) throws Exception{ Directory fsDir = FSDirectory.getDirectory(indexDir, false ); IndexSearcher is = new IndexSearcher(fsDir); Query query = QueryParser.parse(q, "contents" , new StandardAnalyzer()); Hits hits = is.search(query); System.out.println( "Found " + hits.length() + " document(s) that matched query '" + q + "':" ); for ( int i = 0 ; i < hits.length(); i++) { Document doc = hits.doc(i); System.out.println(doc.get( "filename" )); } } |
Выражения, передаваемые QueryParser
, анализируются в соответствии с простой грамматикой. Когда встречается недопустимое выражение, QueryParser
ParseException
.
2,3. Синтаксис выражения QueryParser
Следующие элементы в этом разделе описывают синтаксис, который поддерживает QueryParser
для создания различных типов запросов.
Однократный запрос
Строка запроса только из одного слова преобразуется в базовый TermQuery
.
Фразовый запрос
Чтобы найти группу слов вместе в поле, заключите слова в двойные кавычки. Запрос «hello world» соответствует точному совпадению фразы, требуя, чтобы «hello» и «world» были последовательными терминами для совпадения. Lucene также поддерживает небрежные фразы, когда термины между кавычками не обязательно должны быть в точном порядке. Коэффициент наклона измеряет количество ходов, необходимых для перестановки членов в точный порядок. Если количество ходов меньше указанного коэффициента наклона, это совпадение. QueryParser
анализирует выражение «hello world» ~ 2 как PhraseQuery
с коэффициентом PhraseQuery
2, что позволяет сопоставлять фразы «world hello», «hello world», «hello * world» и «hello * * world», где звездочки обозначают неуместные слова в индексе. Обратите внимание, что «world * hello» не совпадает с коэффициентом наклона 2. Поскольку число ходов, чтобы вернуть его в «hello world», равно 3. Прыжок слова «world» в положение звездочки равен единице, « Привет »позиция два, и третий прыжок делает точное совпадение.
Диапазон запроса
Текстовые запросы или запросы диапазона дат используют синтаксис в квадратных скобках, с TO между начальным и конечным терминами. Тип скобок определяет, является ли диапазон включающим (квадратные скобки) или исключительным (фигурные скобки).
ЗАМЕЧАНИЯ. В запросах, не относящихся к диапазону дат, используются начальный и конечный термины, введенные пользователем без изменений. В случае {Aardvark TO Zebra} термины не в нижнем регистре. Термины начала и конца не должны содержать пробелов, иначе синтаксический анализ не удастся; разрешены только отдельные слова. Анализатор не запускается в начальные и конечные сроки.
Обработка диапазона дат
Когда встречается запрос диапазона (такой как [1/1/03 TO 12/31/03]), код синтаксического анализатора сначала пытается преобразовать начальный и конечный термины в даты. Если термины являются действительными датами, в соответствии с DateFormat.SHORT
и мягким синтаксическим DateFormat.SHORT
, тогда даты преобразуются в их внутреннее текстовое представление (однако, индексация поля даты выходит за рамки данной статьи). Если какой-либо из двух терминов не может быть проанализирован как действительная дата, они оба используются как есть для текстового диапазона.
Подстановочные и префиксные запросы
Если термин содержит звездочку или вопросительный знак, он считается WildcardQuery
, за исключением случаев, когда термин содержит только QueryParser
звездочку и QueryParser
оптимизирует его до PrefixQuery
. Хотя сам по себе WildcardQuery
API поддерживает ведущий подстановочный знак, QueryParser
не допускает этого. Примером подстановочного запроса является w * ldc? Rd , тогда как префикс * запроса оптимизируется как PrefixQuery
.
Нечеткий запрос
FuzzyQuery
Lucene соответствует условиям, близким к указанному. Алгоритм расстояния Левенштейна определяет, насколько близки слагаемые в индексе к заданному целевому слагаемому. «Редактировать расстояние» — это еще один термин для «расстояния Левенштейна» и является мерой сходства между двумя строками, где расстояние измеряется как количество удалений, вставок или замен символов, необходимых для преобразования одной строки в другую. Например, расстояние редактирования между «тремя» и «деревом» равно единице, поскольку требуется удаление только одного символа. Число ходов используется в расчете порога, который является отношением расстояния к длине струны. QueryParser
поддерживает нечеткие запросы, используя QueryParser
тильду для термина. Например, при поиске wuzza ~ будут найдены документы, содержащие «fuzzy» и «wuzzy». Расстояние редактирования влияет на оценку, так что меньшие расстояния редактирования дают больший балл.
Логический запрос
Текстовое построение логических запросов выполняется с использованием операторов AND, OR и NOT. Термины, перечисленные без указания оператора, используют неявный оператор, который по умолчанию равен OR. Запрос abc xyz будет интерпретирован как abc ИЛИ xyz. Размещение NOT перед термином исключает документы, содержащие следующий термин. Отрицательный термин должен быть объединен по крайней мере с одним неотрицательным сроком, чтобы возвратить документы. Каждый из операторов слов в верхнем регистре имеет сокращенный синтаксис, показанный в следующей таблице.
QueryParser
— это быстрый и легкий способ предоставить пользователям мощную конструкцию запросов, но это не для всех. QueryParser
не может создавать все типы запросов, которые могут быть построены с использованием API. Например, PhrasePrefixQuery
не может быть PhrasePrefixQuery
. Вы должны иметь в виду, что все возможности доступны при представлении запроса произвольной формы конечному пользователю. Некоторые запросы могут стать причиной узких мест в производительности. Синтаксис, используемый встроенным QueryParser
может не соответствовать вашим потребностям. Некоторое управление возможно с помощью подкласса QueryParser
, хотя он все еще ограничен.
3. Создать индекс с поиском по индексу
В общем случае приложения обычно должны вызывать только унаследованные
1
|
Searcher.search(org.apache.lucene.search.Query,int) |
или же
1
|
Searcher.search(org.apache.lucene.search.Query,org.apache.lucene.search.Filter,int) |
методы. Для повышения производительности мы можем открыть indexSearcher
и использовать его для всех других поисковых операций. Вот простой пример того, как создать индекс в lucene и выполнить поиск по этому индексу, используя indexSearcher
.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
public void simpleLucene() { Analyzer analyzer = new StandardAnalyzer(); // Store the index in memory: Directory directory = new RAMDirectory(); // To store an index on disk, use this instead (note that the // parameter true will overwrite the index in that directory // if one exists): // Directory directory = FSDirectory.getDirectory("/tmp/myfiles", true); IndexWriter iwriter = new IndexWriter(directory, analyzer, true ); iwriter.setMaxFieldLength( 25000 ); Document doc = new Document(); String text = "This is the text to be indexed." ; doc.add( new Field( "fieldname" , text, Field.Store.YES, Field.Index.TOKENIZED)); iwriter.addDocument(doc); iwriter.close(); // Now search the index: IndexSearcher isearcher = new IndexSearcher(directory); // Parse a simple query that searches for "text": QueryParser parser = new QueryParser( "fieldname" , analyzer); Query query = parser.parse( "text" ); Hits hits = isearcher.search(query); assertEquals( 1 , hits.length()); // Iterate through the results: for ( int i = 0 ; i < hits.length(); i++) { Document hitDoc = hits.doc(i); assertEquals( "This is the text to be indexed." , hitDoc.get( "fieldname" )); } isearcher.close(); directory.close(); } |
4. Различные типы запросов
Lucene поддерживает различные запросы. Вот некоторые из них.
- TermQuery
- BooleanQuery
- WildcardQuery
- PhraseQuery
- PrefixQuery
- MultiPhraseQuery
- FuzzyQuery
- RegexpQuery
- TermRangeQuery
- NumericRangeQuery
- ConstantScoreQuery
- DisjunctionMaxQuery
- MatchAllDocsQuery
4.1 TermQuery
Соответствует документам с полями, содержащими термин (не проанализирован). Термин запрос отображается в Lucene TermQuery
. Следующее соответствует документам, где поле пользователя содержит термин kimchy :
1
2
3
|
{ "term" : { "user" : "kimchy" } } |
Повышение также может быть связано с запросом:
1
2
3
|
{ "term" : { "user" : { "value" : "kimchy" , "boost" : 2.0 } } } |
Или же :
1
2
3
|
{ "term" : { "user" : { "term" : "kimchy" , "boost" : 2.0 } } } |
В Lucene можно искать определенное слово, которое было проиндексировано, с TermQuery
класса TermQuery
. В этом руководстве будут сравниваться запросы TermQuery
поисками QueryParser
, а также показываться некоторые нюансы, связанные с запросом термина.
4.2 BooleanQuery
Мы можем запускать поиск в нескольких полях в Lucene, используя либо API-интерфейс BooleanQuery
либо используя MultiFieldQueryParser
для анализа текста запроса. Например, если индекс имеет 2 поля FirstName
и LastName
и если вам нужно найти «John» в поле FirstName
и «Travis» в поле LastName
можно использовать BooleanQuery
как таковой:
1
2
3
4
5
6
7
|
BooleanQuery bq = new BooleanQuery(); Query qf = new TermQuery( new Lucene.Net.Index.Term( "FirstName" , "John" )); Query ql = new TermQuery( new Lucene.Net.Index.Term( "LastName" , "Travis" )); bq.Add(qf, BooleanClause.Occur.MUST); bq.Add(ql, BooleanClause.Occur.MUST); IndexSearcher srchr = new IndexSearcher(@ "C:\\indexDir" ); srchr.Search(bq); |
4.3 WildcardQuery
Соответствует документам, поля которых соответствуют шаблону (не анализируются). Поддерживаются подстановочные знаки *, которые соответствуют любой последовательности символов (включая пустую), и?, Которые соответствуют любому отдельному символу. Обратите внимание, что этот запрос может быть медленным, поскольку он должен повторяться по многим терминам. Чтобы предотвратить чрезвычайно медленные запросы с подстановочными знаками, термин с подстановочными знаками не должен начинаться с одного из символов подстановки * или?. Запрос с подстановочными знаками сопоставляется с Lucene WildcardQuery.
1
2
3
|
{ "wildcard" : { "user" : "ki*y" } } |
Повышение также может быть связано с запросом:
1
2
3
|
{ "wildcard" : { "user" : { "value" : "ki*y" , "boost" : 2.0 } } } |
Или же :
1
2
3
|
{ "wildcard" : { "user" : { "wildcard" : "ki*y" , "boost" : 2.0 } } } |
Этот многоточечный запрос позволяет контролировать, как он переписывается с помощью параметра rewrite.
4.4 PhraseQuery
В Lucene PhaseQuery
можно использовать для запроса последовательности терминов, где термины не обязательно должны быть рядом или по порядку. PhaseQuery
setSlop()
объекта setSlop()
можно использовать для установки количества слов между различными словами в фразе запроса.
Мы можем использовать PhraseQuery
как это,
1
2
3
4
5
6
|
Term term1 = new Term(FIELD_CONTENTS, string1); Term term2 = new Term(FIELD_CONTENTS, string2); PhraseQuery phraseQuery = new PhraseQuery(); phraseQuery.add(term1); phraseQuery.add(term2); phraseQuery.setSlop(slop); |
4.5 PrefixQuery
Соответствует документам, имеющим поля, содержащие термины с указанным префиксом (не анализируется). Запрос префикса отображается на Lucene PrefixQuery
. Следующее соответствует документам, где поле пользователя содержит термин, начинающийся с ki :
1
2
3
|
{ "prefix" : { "user" : "ki" } } |
Повышение также может быть связано с запросом:
1
2
3
|
{ "prefix" : { "user" : { "value" : "ki" , "boost" : 2.0 } } } |
Или же :
1
2
3
|
{ "prefix" : { "user" : { "prefix" : "ki" , "boost" : 2.0 } } } |
Этот многоточечный запрос позволяет контролировать, как он переписывается с помощью параметра rewrite.
4.6 MultiPhraseQuery
Встроенный MultiPhraseQuery
— это определенно нишевый запрос, но он потенциально полезен. MultiPhraseQuery
похож на PhraseQuery
за исключением того, что он допускает несколько терминов на позицию. Вы можете достичь того же логического эффекта, хотя и с высокой производительностью, перечислив все возможные комбинации фраз и используя BooleanQuery
для «ИЛИ» их вместе.
Например, предположим, что мы хотим найти все документы о быстрых лисах, с быстрым или быстрым, за которым следует лиса. Один из подходов состоит в том, чтобы выполнить запрос «Быстрая лиса» ИЛИ «Быстрая лиса». Другой вариант — использовать MultiPhraseQuery
.
4.7 FuzzyQuery
FuzzyQuery
можно разделить на две категории, а. нечеткий как этот запрос & b. нечеткое, как это поле querya. Нечеткий подобный этому запросу — Нечеткий подобный этому запросу находит документы, которые «похожи» на предоставленный текст, запуская его в одном или нескольких полях.
1
2
3
4
5
6
7
|
{ "fuzzy_like_this" : { "fields" : [ "name.first" , "name.last" ], "like_text" : "text like this one" , "max_query_terms" : 12 } } |
fuzzy_like_this можно сократить до flt.
Параметры верхнего уровня fuzzy_like_this включают в себя:
-
fields
-> Список полей для запуска, более похожих на этот запрос. По умолчанию используется поле _all. -
like_text
-> Текст для поиска документов, как это, обязательно. -
ignore_tf
-> Следует ли игнорировать термин «частота». По умолчанию false. -
max_query_terms
-> Максимальное количество условий запроса, которые будут включены в любой сгенерированный запрос. По умолчанию 25. -
fuzziness
-> минимальное сходство вариантов вариантов. По умолчанию 0,5. Смотрите раздел под названием «Fuzzinessedit». -
prefix_length
-> Длина обязательного общего префикса для вариантов вариантов. По умолчанию 0. -
boost
-> Устанавливает значение повышения запроса. По умолчанию 1.0. -
analyzer
-> Анализатор, который будет использоваться для анализа текста. По умолчанию используется анализатор, связанный с полем.
Размывает ВСЕ термины, представленные в виде строк, а затем выбирает лучшие n дифференцирующих терминов. По сути это смешивает поведение FuzzyQuery
и MoreLikeThis
но с особым учетом нечетких скоринговых факторов. Как правило, это приводит к хорошим результатам для запросов, в которых пользователи могут предоставлять подробности по ряду полей и не знать синтаксиса логических запросов, а также хотят иметь степень нечеткого соответствия и быстрый запрос.
Для каждого исходного термина нечеткие варианты хранятся в BooleanQuery
без координатного фактора (потому что мы не ищем совпадений для нескольких вариантов в одном документе). Кроме того, специализированный TermQuery
используется для вариантов и не использует IDF этого варианта термина, потому что это предпочло бы более редкие термины, такие как орфографические ошибки. Вместо этого все варианты используют один и тот же рейтинг IDF (тот, который используется для термина исходного запроса), и это учитывается при повышении варианта. Если термин исходного запроса не существует в индексе, используется средняя IDF вариантов. нечеткое, как это поле запроса–
Запрос fuzzy_like_this_field такой же, как запрос fuzzy_like_this , за исключением того, что он выполняется для одного поля. Он обеспечивает более качественный DSL-запрос по сравнению с общим запросом fuzzy_like_this и поддерживает запрос типизированных полей (автоматически переносит типизированные поля с типом filter, чтобы они соответствовали только определенному типу).
1
2
3
4
5
6
7
8
|
{ "fuzzy_like_this_field" : { "name.first" : { "like_text" : "text like this one" , "max_query_terms" : 12 } } } |
Поле fuzzy_like_this_field может быть сокращено до flt_field. Параметры верхнего уровня fuzzy_like_this_field включают в себя:
- like_text -> Текст для поиска документов, как это, обязательно.
- ignore_tf -> Следует ли игнорировать термин «частота». По умолчанию false.
- max_query_terms -> Максимальное количество условий запроса, которые будут включены в любой сгенерированный запрос. По умолчанию 25.
- нечеткость -> нечеткость вариантов вариантов. По умолчанию 0,5. Смотрите раздел под названием «Fuzzinessedit».
- prefix_length -> Длина обязательного общего префикса для вариантов вариантов. По умолчанию 0.
- boost -> Устанавливает значение повышения запроса. По умолчанию 1.0.
- анализатор -> Анализатор, который будет использоваться для анализа текста. По умолчанию используется анализатор, связанный с полем.
4.8 RegexpQuery
Запрос регулярного выражения позволяет вам использовать запросы с регулярными выражениями. См. Синтаксис регулярных выражений для получения подробной информации о поддерживаемом языке регулярных выражений.
Примечание. Производительность запроса регулярного выражения в значительной степени зависит от выбранного регулярного выражения. Совпадение всего, как. * Очень медленное, а также использование регулярных выражений. Если возможно, вы должны попытаться использовать длинный префикс, прежде чем ваше регулярное выражение начинается. Подстановочные знаки, такие как . *? + , В основном снижают производительность.
1
2
3
4
5
|
{ "regexp" :{ "name.first" : "s.*y" } } |
Повышение также поддерживается
1
2
3
4
5
6
7
8
|
{ "regexp" :{ "name.first" :{ "value" : "s.*y" , "boost" :1.2 } } } |
Вы также можете использовать специальные флаги
1
2
3
4
5
6
7
8
|
{ "regexp" :{ "name.first" : { "value" : "s.*y" , "flags" : "INTERSECTION|COMPLEMENT|EMPTY" } } } |
Возможные флаги: ALL
, ANYSTRING
, ANYSTRING
, ANYSTRING
, EMPTY
, INTERSECTION
, INTERVAL
или NONE
. Запросы регулярных выражений поддерживаются запросами regexp и query_string . Механизм регулярных выражений Lucene не является Perl-совместимым, но поддерживает меньший диапазон операторов.
Стандартные операторы
Привязка Большинство механизмов регулярных выражений позволяют вам сопоставить любую часть строки. Если вы хотите, чтобы шаблон регулярного выражения начинался в начале строки или заканчивался в конце строки, то вам нужно специально привязать его, используя ^, чтобы указать начало, или $, чтобы указать конец. Шаблоны Lucene всегда привязываются. Указанный шаблон должен соответствовать всей строке. Для строки «abcde» :
1
|
ab.* # match |
1
|
abcd # no match |
Разрешенные персонажи
Любые символы Юникода могут использоваться в шаблоне, но некоторые символы зарезервированы и должны быть экранированы. Стандартные зарезервированные символы:
, ? + * | {} [] () ”\
Если вы включите дополнительные функции (см. Ниже), то эти символы также могут быть зарезервированы:
# @ & <> ~
Любой зарезервированный символ может быть экранирован обратной косой чертой «\ *», включая буквенный символ обратной косой черты:
«\\»
Кроме того, любые символы (кроме двойных кавычек) интерпретируются буквально, когда они заключены в двойные кавычки:
джон»@ smith.com»
Подходим любой персонаж
Период «.» может использоваться для представления любого символа. Для строки «abcde»:
1
|
ab... # match |
1
|
a.c.e # match |
Один или больше
Знак «+» можно использовать для повторения предыдущего кратчайшего шаблона один или несколько раз. Для строки «aaabbb»:
1
|
a+b+ # match |
1
|
aa+bb+ # match |
1
|
a+.+ # match |
1
|
aa+bbb+ # no match |
Ноль или более-
Звездочку «*» можно использовать для совпадения с предыдущим кратчайшим шаблоном ноль или более раз. Для строки «aaabbb»:
1
|
a*b* # match |
1
|
a*b*c* # match |
1
|
.*bbb.* # match |
1
|
aaa*bbb* # match |
Ноль или один
Вопросительный знак «?» делает предыдущий кратчайший образец необязательным. Это соответствует нулю или один раз. Для строки «aaabbb»:
1
|
aaa?bbb? # match |
1
|
aaaa?bbbb? # match |
1
|
.....?.? # match |
1
|
aa?bb? # no match |
Min-к-макс
С помощью фигурных скобок «{}» можно указать минимальное и (необязательно) максимальное количество повторений предыдущего кратчайшего шаблона. Разрешенные формы:
1
|
{5} # repeat exactly 5 times |
1
|
{2,5} # repeat at least twice and at most 5 times |
1
|
{2,} # repeat at least twice |
Для строки «aaabbb»:
1
|
a{3}b{3} # match |
1
|
a{2,4}b{2,4} # match |
1
|
a{2,}b{2,} # match |
1
|
.{3}.{3} # match |
1
|
a{4}b{4} # no match |
1
|
a{4,6}b{4,6} # no match |
1
|
a{4,}b{4,} # no match |
Группировка
Скобки «()» могут быть использованы для формирования подшаблонов. Перечисленные выше количественные операторы работают с кратчайшим предыдущим шаблоном, который может быть группой. Для строки «ababab»:
1
|
(ab)+ # match |
1
|
ab(ab)+ # match |
1
|
(..)+ # match |
1
|
(...)+ # no match |
1
|
(ab)* # match |
1
|
abab(ab)? # match |
1
|
ab(ab)? # no match |
1
|
(ab){3} # match |
1
|
(ab){1,2} # no match |
перемежаемость
Символ трубы «|» действует как оператор ИЛИ. Совпадение будет успешным, если шаблон с левой стороны ИЛИ с правой стороны совпадает. Чередование применяется к самому длинному шаблону, а не к самому короткому. Для строки «aabb»:
1
|
aabb|bbaa # match |
1
|
aacc|bb # no match aa(cc|bb) # match |
1
|
a+|b+ # no match |
1
|
a+b+|b+a+ # match |
1
|
a+(b|c)+ # match |
Классы персонажей
Диапазоны потенциальных символов могут быть представлены как классы символов, заключив их в квадратные скобки «[]». Ведущий ^ отрицает класс персонажа. Разрешенные формы:
1
|
[abc] # 'a' or 'b' or 'c' |
1
|
[a-c] # 'a' or 'b' or 'c' |
1
|
[-abc] # '-' or 'a' or 'b' or 'c' |
1
|
[abc\\-] # '-' or 'a' or 'b' or 'c' |
1
|
[^a-c] # any character except 'a' or 'b' or 'c' |
1
|
[^a-c] # any character except 'a' or 'b' or 'c' |
1
|
[-abc] # '-' or 'a' or 'b' or 'c' |
1
|
[abc\\-] # '-' or 'a' or 'b' or 'c' |
Обратите внимание, что тире «-» указывает диапазон символов, если это не первый символ или если он не экранирован обратной косой чертой. Для строки «abcd»:
1
|
ab[ cd ]+ # match |
1
|
[a-d]+ # match |
1
|
[^a-d]+ # no match |
4.9 TermRangeQuery
Query
который соответствует документам в пределах диапазона условий. Этот запрос сопоставляет документы, ищущие термины, попадающие в указанный диапазон, в соответствии с String#compareTo(String)
, если не Collator
. Он не предназначен для числовых диапазонов.
Вот пример того, как использовать TermRangeQuery
в Lucene,
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
private Query createQuery(String field, DateOperator dop) throws UnsupportedSearchException { Date date = dop.getDate(); DateResolution res = dop.getDateResultion(); DateTools.Resolution dRes = toResolution(res); String value = DateTools.dateToString(date, dRes); switch (dop.getType()) { case ON: return new TermQuery( new Term(field ,value)); case BEFORE: return new TermRangeQuery(field, DateTools.dateToString(MIN_DATE, dRes), value, true , false ); case AFTER: return new TermRangeQuery(field, value, DateTools.dateToString(MAX_DATE, dRes), false , true ); default : throw new UnsupportedSearchException(); } } |
4.10 NumericRangeQuery
NumericRangeQuery
, который соответствует числовым значениям в указанном диапазоне. Чтобы использовать это, вы должны сначала проиндексировать числовые значения. Мы можем объединить NumericRangeQuery
с TermQuery
следующим образом:
1
2
3
4
|
String termQueryString = "title:\\" hello world\\ "" ; Query termQuery = parser.parse(termQueryString); Query pageQueryRange = NumericRangeQuery.newIntRange( "page_count" , 10 , 20 , true , true ); Query query = termQuery.combine( new Query[]{termQuery, pageQueryRange}); |
4.11 ConstantScoreQuery
Запрос, который оборачивает другой запрос или фильтр и просто возвращает постоянную оценку, равную увеличению запроса, для каждого документа, который соответствует фильтру или запросу. Поэтому для запросов он просто отбрасывает все оценки и возвращает постоянную.
1
2
3
4
5
6
7
8
|
{ "constant_score" : { "filter" : { "term" : { "user" : "kimchy" } }, "boost" : 1.2 } } |
Объект фильтра может содержать только элементы фильтра, но не запросы. Фильтры могут быть намного быстрее по сравнению с запросами, поскольку они не выполняют никакой оценки, особенно когда они кэшируются. Запрос также может быть включен в запрос constant_score:
1
2
3
4
5
6
7
8
|
{ "constant_score" : { "query" : { "term" : { "user" : "kimchy" } }, "boost" : 1.2 } } |
4.12 DisjunctionMaxQuery
Запрос, который генерирует объединение документов, созданных его подзапросами, и оценивает каждый документ с максимальной оценкой для этого документа, полученной любым подзапросом, плюс приращение разрыва связи для любых дополнительных соответствующих подзапросов.
Это полезно при поиске слова в нескольких полях с разными коэффициентами усиления (чтобы поля не могли быть эквивалентно объединены в одно поле поиска). Мы хотим, чтобы основной счет был тот, который связан с наибольшим усилением, а не сумма баллов по полю (как даст булев запрос). Если запрос «слон-альбинос», это гарантирует, что «альбинос», соответствующий одному полю, и «слон», соответствующий другому, получат более высокий балл, чем «альбинос», соответствующий обоим полям. Чтобы получить этот результат, используйте как Boolean Query, так и DisjunctionMaxQuery
: для каждого термина DisjunctionMaxQuery ищет его в каждом поле, в то время как набор этих DisjunctionMaxQuery объединяется в BooleanQuery
.
Возможность прерывания связей позволяет оценивать результаты, включающие один и тот же термин в нескольких полях, лучше, чем результаты, включающие этот термин только в лучшее из этих нескольких полей, не путая это с лучшим случаем двух разных терминов в нескольких полях. по умолчанию tie_breaker — 0.0. Этот запрос сопоставляется с Lucene DisjunctionMaxQuery
.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
{ "dis_max" : { "tie_breaker" : 0.7, "boost" : 1.2, "queries" : [ { "term" : { "age" : 34 } }, { "term" : { "age" : 35 } } ] } } |
4.13 MatchAllDocsQuery
Запрос, который соответствует всем документам. Карты для Lucene MatchAllDocsQuery
.
1
2
3
|
{ "match_all" : { } } |
Который также может иметь повышение, связанное с этим:
1
2
3
|
{ "match_all" : { "boost" : 1.2 } } |