一、基本查询语法
所有的 REST 搜索请求使用_search 接口,既可以是 GET 请求,也可以是 POST请求,也可以通过在搜索 URL 中指定索引来限制范围。
_search 接口有两种请求方法,一种是基于 URI 的请求方式,另一种是基于
请求体的方式,无论哪种,他们执行的语法都是基于 DSL(ES 为我们定义的查询语言,基于 JSON 的查询语言),只是形式上不同。我们会基于请求体的方式来学习。
语法:
get indexName(aliasName)/_search
{
"query":{ "match_all":{}},
"size": 10,
"from": 0,
"_source": ["xxx","xxx"]
"sort": ""
}
from和size参数:
分页参数,from代表从第几页开始,size代表了返回文档的数量。需要注意的是,为了确定第 2 页的 10 项结果,Elasticsearch 必须要计算前 20 个结果。如果结果集合不断增加,获取某些靠后的翻页将会成为代价高昂的操作。
举例: 如果发送的 from 值是 7,size 值是 5,那么 Elasticsearch 将返回第 8、9、10、 11 和 12 项结果(由于 from 参数是从 0 开始,指定 7 就是从第 8项结果开始)。如果没有发送这两个参数,Elasticsearch 默认从第一项结果开始( 第 0 项结果),在回复中返回 10 项结果。
需要注意的是,from 与 size 的和不能超过 index. max_result_window 这个索引配置项设置的值。默认情况下这个配置项的值为 10000,所以如果要查询 10000 条以后的文档,就必须要增加这个配置值。例如,要检索第 10000 条开始的 200 条数据,这个参数的值必须要大于 10200,否则将会抛出类似“ Result window is too large’的异常。
由此可见,Elasticsearch 在使用 from 和 size 处理分页问题时会将所有数据全部取出来,然后再截取用户指定范围的数据返回。所以在查询非常靠后的数据时,即使使用了 from 和 size 定义的分页机制依然有内存溢出的可能,而 max_result_ window 设置的 10000 条则是对 Elastiesearch 的一.种保护机制。
_source参数:
指定_source
字段如何返回。默认是返回完整的_ source 字段。
通过配置_ source
,将过滤返回的字段。如果索引的文档很大,而且无须结果中的全部内容,就使用这个功能。请注意,如果想使用它,就不能在索引映射中关闭_ source
字段。
元字段_source
中存储了文档的原始数据。如果请求中没有指定_source
,Elasticsearch 默认返回整个_ source
, 或者如果_ source
没有存储,那么就只返回匹配文档的元数据:_ id、_type、_index 和_score。
你不仅可以返回字段列表,还可以指定通配符。例如,如果想同时返回" DestCountry “和” DestWeather “字段,可以这样配置_ source: “Dest*”。 也可以使用通配字符串的数组来指定多个通配符,例如_ source:[” Origin*“,”* Weather "]。
不仅可以指定哪些字段需要返回,还可以指定哪些字段无须返回。比如:
get indexName/_search{
"_source": {
"includes": ["*.lon",
"*.lat"],
"excludes": "DestLocation.*"
}
}
sort参数:
如果没有指定 sort 排序选项,Elasticsearch 返回匹配的文档的时候,按照_ score 取值的降序来排列,这样最为相关的(得分最高的)文档就会排名在前。为了对字段进行升序或降序排列,指定映射的数组,而不是字段的数组。通过在 sort 中指定字段列表或者是字段映射,可以在任意数量的字段上进行排序。
例如:
get indexName/_search{
"from": 100,
"size": 20,
"query": {
"match_all": {
}
},
"_source": ["Origin*",
"*Weather"],
"sort": [{
"DistanceKilometers": "asc"
},
{
"FlightNum": "desc"
}]
}
二、 Query参数详解
_search
接口的query参数支持多种类型的查询,下面详细讲解每种类型的查询。
2.1 term 查询
词项精准查询。对于字符串而言,字符串的精确匹配是指字符的大小写,字符的数量和位置都是相同的,词条(term)查询使用字符的完全匹配方式进行文本搜索,词条查询不会分析(analyze)查询字符串,给定的字段必须完全匹配词条查询中指定的字符串。
例如:
精准匹配,可以查询出结果,但是如果是如下查询:
就没有结果。因此可以把 term 查询理解为 SQL 语句中 where 条件的等于号。
2.2 terms 查询
可以把 terms 查询理解为 SQL 语句中 where 条件的 in 操作符:
get indexName/_search{
"query": {
"terms": {
"OriginCityName": ["Frankfurt am Main","Cape Town"]
}
}
}
Elasticsearch 在 terms 查询中还支持跨索引查询,这类似于关系型数据库中的一对多或多对多关系。比如,用户与文章之间就是一对多关系,可以在用户索引中存储文章编号的数组以建立这种对应关系,而将文章的实际内容保存在文章索引中( 当然也可以在文章中保存用户 ID)。如果想将 ID 为 1 的用户发表的所有文章都找出来,在文章索引中查询时为:
POST /articles/search{
"query": {
"terms": {
"_id": {
"index": "users",
"id": 1,
"path": "articles"
}
}
}
}
在上面的例子中,terms 要匹配的字段是 id, 但匹配值则来自于另一个索引。这里用到了 index、id 和 path 三个参数,它们分别代表要引用的索引、文档 ID和字段路径。在上面的例子中,先会到 users 索引中在找 id 为 1 的文档,然后取出 articles 字段的值与 articles 索引里的_id 做对比,这样就将用户 1 的所有文章都取出来了。
2.3 range 查询
range 查询和过滤器的含义是不言而喻的,它们查询介于一定范围之内的值,适用于数字、日期甚至是字符串。
为了使用范围查询,需要指定某个字段的上界和下界值。例如:
get indexName/_search{
"query": {
"range": {
"FlightDelayMin": {
"gte": 100,
"lte": 200
}
}
}
}
gte:大于等于 (greater than and equal)
gt:大于 (greater than)
lte:小于等于 (less than and equal)
lt:大于 (less than )
boost:相关性评分。
2.4 prefix 查询
prefix 查询允许你根据给定的前缀来搜索词条,这里前缀在同样搜索之前是没有经过分析的。例如:
get indexname/_search{
"query": {
"prefix": {
"DestCountry": "C"
}
}
}
找到DestCountry字段中所有以 C 开头的文档。
2.5 wildcard 查询和 regexp 查询
wildcard 查询就是通配符查询。
使用字符串可以让 Elasticsearch 使用*通配符替代任何数量的字符(也可以不含)或者是使用?通配符替代单个字符。
例如,有 5 个单词:“bacon”、“barn” 、“ban” 和“baboon” 。
“bam”,ba*n
的查询会匹配“bacon”“barn” “ban” 和“baboon”,这是因为*
号可以匹配任何字符序列,而查询“ba?n” 只会匹配“barn",因为?任何时候都需要匹配一个单独字符。
也可以混合使用多个*
和?字符来匹配更为复杂的通配模板,比如 f*f?x 就可以匹配 firefox。
get indexname/_search{
"query": {
"wildcard": {
"Dest": "*Marco*"
}
}
}
Elasticsearch 也支持正则 regexp 查询,例如:
get indexname/_search{
"query": {
"regexp": {
"字段名": "正则表达式"
}
}
}