官网地址:https://www.elastic.co/guide/en/elasticsearch/reference/current/term-level-queries.html
部分匹配允许用户指定查找词的一部分并找出所有包含这部分片段的词。
匹配包含具有指定前缀的项(not analyzed)的字段的文档。前缀查询对应Lucene的PrefixQuery。
GET /_search
{
"query": {
"prefix": {
"user.id": {
"value": "ki"
}
}
}
}
<field>
.rewrite
parameter.You can speed up prefix queries using theindex_prefixes
mapping parameter. If enabled, Elasticsearch indexes prefixes between 2 and 5 characters in a separate field. This lets Elasticsearch run prefix queries more efficiently at the cost of a larger index.
您可以使用index_prefixes映射参数来加速前缀查询。 如果启用,Elasticsearch会在一个单独的字段中索引2到5个字符之间的前缀。 这使Elasticsearch可以以更大的索引为代价更有效地运行前缀查询。
Prefix queries will not be executed ifsearch.allow_expensive_queries
is set to false. However, ifindex_prefixes
are enabled, an optimised query is built which is not considered slow, and will be executed in spite of this setting.
如果将search.allow_expensive_queries设置为false,则不会执行前缀查询。 但是,如果启用了index_prefixes,则会构建一个优化的查询,该查询并不算慢,尽管有此设置也将执行该查询。
Returns documents that contain terms within a provided range.
GET /_search
{
"query": {
"range": {
"age": {
"gte": 10,
"lte": 20,
"boost": 2.0
}
}
}
}
date
values in the query. format
provided in the<field>
's mapping. This value overrides that mapping format.format
.range
fields. Valid values are:date
values in the query to UTC.+01:00
or -08:00
, and IANA time zone IDs, such as America/Los_Angeles
.time_zone
parameter, see Time zone in range
queries.{
"query" : {
"constant_score" : {
"filter" : {
"range" : {
"price" : {
"gte" : 20,
"lt" : 40
}
}
}
}
}
}
range
查询同样可以应用在日期字段上:
"range" : {
"timestamp" : {
"gt" : "2014-01-01 00:00:00",
"lt" : "2014-01-07 00:00:00"
}
}
当使用它处理日期字段时,range
查询支持对日期计算(date math)进行操作,比方说,如果我们想查找时间戳在过去一小时内的所有文档:
"range" : {
"timestamp" : {
"gt" : "now-1h"
}
}
{
"query": {
"range": {
"timestamp": {
"gte": "now-1d/d",
"lt": "now/d"
}
}
}
}
这个过滤器会一直查找时间戳在过去一个小时内的所有文档,让过滤器作为一个时间滑动窗口(sliding window)来过滤文档。
日期计算还可以被应用到某个具体的时间,并非只能是一个像 now 这样的占位符。只要在某个日期后加上一个双管符号 (||
) 并紧跟一个日期数学表达式就能做到:
"range" : {
"timestamp" : {
"gt" : "2014-01-01 00:00:00",
"lt" : "2014-01-01 00:00:00||+1M" #早于 2014 年 1 月 1 日加 1 月(2014 年 2 月 1 日 零时)
}
}
日期计算是日历相关(calendar aware)的,所以它不仅知道每月的具体天数,还知道某年的总天数(闰年)等信息。更详细的内容可以参考:时间格式参考文档。
You can use thetime_zone
parameter to convertdate
values to UTC using a UTC offset. For example:
您可以使用time_zone参数使用UTC偏移量将日期值转换为UTC。 例如:
GET /_search
{
"query": {
"range": {
"timestamp": {
"time_zone": "+01:00", // Indicates that date values use a UTC offset of +01:00.
"gte": "2020-01-01T00:00:00", // With a UTC offset of +01:00, Elasticsearch converts this date to 2019-12-31T23:00:00 UTC.
"lte": "now" // The time_zone parameter does not affect the now value.
}
}
}
}
格式化的日期将使用指定的默认format(格式)解析date(日期)字段,但可以通过将格式参数传递到range (范围)查询来覆盖默认格式:
GET _search
{
"query": {
"range" : {
"timestamp" : {
"gte": "01/01/2012",
"lte": "2013",
"format": "dd/MM/yyyy||yyyy"
}
}
}
}
range
查询同样可以处理字符串字段, 字符串范围可采用字典顺序(lexicographically)或字母顺序(alphabetically)。例如,下面这些字符串是采用字典序(lexicographically)排序的:
在倒排索引中的词项就是采取字典顺序(lexicographically)排列的,这也是字符串范围可以使用这个顺序来确定的原因。
如果我们想查找从a
到b
(不包含)的字符串,同样可以使用range
查询语法:
"range" : {
"title" : {
"gte" : "a",
"lt" : "b"
}
}
数字和日期字段的索引方式使高效地范围计算成为可能。 但字符串却并非如此,要想对其使用范围过滤,Elasticsearch 实际上是在为范围内的每个词项都执行
term
过滤器,这会比日期或数字的范围过滤慢许多。字符串范围在过滤 低基数(low cardinality) 字段(即只有少量唯一词项)时可以正常工作,但是唯一词项越多,字符串范围的计算会越慢。
Regular Expressions 搜索也即正则搜索是非常耗时的。正则表达式是一种使用 placeholder(称为运算符)匹配数据中的模式的方法。 有关regexp查询支持的运算符的列表,请参阅 Regular expression syntax。
regexp允许使用正则表达式进行term查询.注意regexp如果使用不正确,会给服务器带来很严重的性能压力。比如.*开头的查询,将会匹配所有的倒排索引中的关键字,这几乎相当于全表扫描,会很慢。因此如果可以的话,最好在使用正则前,加上匹配的前缀。在正则中如果使用.*?
或者+
都会降低查询的性能。
GET /_search
{
"query": {
"regexp": {
"user.id": {
"value": "k.*y",
"flags": "ALL",
"case_insensitive": true,
"max_determinized_states": 10000,
"rewrite": "constant_score"
}
}
}
}
10000
.rewrite
parameter.如果将search.allow_expensive_queries设置为false,则将不会执行正则表达式查询。
字符 | 含义 |
---|---|
. | 只能代指任意一个字符 |
* | 重复前一位匹配(0次或者多次) |
? | 重复前一位匹配(0次或者1次) |
+ | 重复前一位匹配(1次或者多次) |
{
"query": {
"regexp": {
"drugname.keyword": {
"value": ".*西地吡.罗昔康片.*",
"flags_value": 65535,
"max_determinized_states": 10000,
"boost": 1
}
}
}
}
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
String reg = ".*" + CharacterUtil.replaceAllForRegexp(keyword) + ".*";
BoolQueryBuilder drugNameBuilder = QueryBuilders.boolQuery();
drugNameBuilder.must(QueryBuilders.regexpQuery("drugname.keyword", reg));
备注:如果keyword里边有特殊字符,可以手动将特殊字符替换成(.)
q.replace("\"", ".").replace("?", ".").replace("*", ".").replace("^", ".").replace("$", ".").replace("+", ".").replace("|", ".").replace("{", ".") .replace("}", ".").replace("[", ".") .replace("]", ".").replace("(", ".").replace(")", ".").replace("\\", ".")
特殊字符:. ? + * | { } [ ] ( ) " \
实际使用 regexp 搜索时,我们必须记住如下的事项:
如果您确实需要匹配 token 的末尾,只需使用 reverse 过滤器为它们建立索引。下面,我们用一个具体的例子来实现。
首先,我们为 reverse_example 建立一个 mapping:
PUT reverse_example
{
"settings": {
"analysis": {
"analyzer": {
"whitespace_reverse": {
"tokenizer": "whitespace",
"filter": [
"reverse"
]
}
}
}
},
"mappings": {
"properties": {
"content": {
"type": "text",
"fields": {
"reversed": {
"type": "text",
"analyzer": "whitespace_reverse"
}
}
}
}
}
}
在这里 content 是一个 multi-field 的字段。content.reversed 将使用 whitespace_reverse 分析器来对我们的字段进行分词。这个分析器将会对术语进行倒序处理。比如:
GET reverse_example/_analyze
{
"tokenizer": "standard",
"filter": [
"reverse"
],
"text": "quick fox jumps"
}
Response:
{
"tokens":[
{
"token":"kciuq",
"start_offset":0,
"end_offset":5,
"type":"<ALPHANUM>",
"position":0
},
{
"token":"xof",
"start_offset":6,
"end_offset":9,
"type":"<ALPHANUM>",
"position":1
},
{
"token":"spmuj",
"start_offset":10,
"end_offset":15,
"type":"<ALPHANUM>",
"position":2
}
]
}
PUT reverse_example/_doc/1
{
"content": "This is a good network"
}
GET reverse_example/_search
{
"query": {
"regexp": {
"content.reversed": "krow.*"
}
}
}
我们通过上面的方法把通配符在前面的搜索修改成为通配符在后面的 regexp 搜索。
参考:https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-reverse-tokenfilter.html
与prefix
前缀查询的特性类似,wildcard
通配符查询也是一种底层基于词的查询,与前缀查询不同的是它允许指定匹配的正则式。它使用标准的 shell 通配符查询:?
匹配任意字符,*
匹配 0 或多个字符。
以下搜索返回文档,其中user.id字段包含以ki开头和y结尾的术语。 这些匹配项可以包括kiy,kity或kimchy。
GET /_search
{
"query": {
"wildcard": {
"user.id": {
"value": "ki*y",
"boost": 1.0,
"rewrite": "constant_score"
}
}
}
}
<field>
.This parameter supports two wildcard operators:?
, which matches any single character*
, which can match zero or more characters, including an empty oneWildcard queries will not be executed if
search.allow_expensive_queries
is set to false.
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。