elasticsearch 搜索提供了多种查询数据的方式,例如 query string 以及_search方式,方便我们根据不同的需求查询数据,同时在查询参数中,可以指定结果的算分策略,能够的到更加符合需求的结果。本文主要从使用方式出发,介绍查询的基础用法
-
URI Search
-
在URL 中使用查询参数
-
-
Request Body Search
-
使用ES提供的,基于JSON格式的更加完备的(Query Domain Specific Language DSL)
-
指定查询索引
| 语法 | 范围 |
|---|---|
| /_search | 集群上所有的索引 |
| /index1/_search | index1索引上的查询 |
| /index1, index2/_search | index1和index2上的查询 |
| /index*/_search | 以index开头的索引 |
URI查询
-
使用”q”,指定查询字符
-
“query string syntax”, KV键值对
-
df: 默认字段,不指定时,会对所有字段进行查询 -
Sort排序 -
from和size用于分页 -
Profile可以查看查询是如何被执行
http://localhost:9200/index1/_search?q=field:value&def=title&sort=year:desc&from=O&size=10&timeout=1s
{"profile": true}
Query String Syntax
-
指定字段 VS 泛查询
-
指定字段查询: q = title:2012
-
范查询:q=2012
-
泛查询会查询所有的字段,这时会降低查询的性能。
-
-
Term VS Phrase
-
Beautifu Mind等效于Beautiful OR Mind -
“
Beautiful Mind“等效于 Beautiful AND Mind, Phrase 查询,还要求前后顺序保持一致
-
-
分组与引号
-
分组使用:title: (Beautiful and Mind), 使用Bool查询
-
引号: “Beautiful Mind”, 使用Phrase查询
-
-
布尔操作
-
AND / OR / NOT 或者 && / || / !
-
必须大写
-
title: (matrx NOT reloaded)
-
-
-
分组
-
+表示must -
-表示must_not -
title: (+matrix -reloaded)
-
-
范围查询
-
区间表示:
[]闭区间,{}开区间-
year: {2019 TO 2018}
-
year: [* TO 2018]
-
-
-
算数符号
-
year: > 2010
-
year: (>2010 && <= 2018)
-
year: (+>2010 +<2018)
-
-
通配符查询 (通配符查询效率低,占用内存大,不建议使用, 特别放在最前面)
-
?代表1个字符,*代表0或多个字符-
title: mi?d
-
title: be*
-
-
-
正则表达式
-
title: [bt]oy
-
-
模糊匹配与近似查询
-
title: befutifl~1
-
title: “lord rings” ~ 2 // 中间相隔的字符位置
-
GET /movies/_search?q=2012&df=title
{
"profile": "true"
}
# 发查询,针对_all ,所有字段
GET /movies/_search?q=2012
{
"profile": "true"
}
# 指定字段
GET /movies/_search?q=title:2012
{
"profile": "true"
}
# 使用引号, Phrase 查询
GET /movies/_search?q=title:"Beautiful Mind"
{
"profile": "true"
}
# 使用引号, Mind 为泛查询
GET /movies/_search?q=title:Beautiful Mind
{
"profile": "true"
}
# 使用引号, Bool 查询
GET /movies/_search?q=title:(Beautiful Mind)
{
"profile": "true"
}
# 查找美丽心灵
GET /movies/_search?q=title:(Beautiful AND Mind)
{
"profile": "true"
}
# 查找美丽心灵
GET /movies/_search?q=title:(Beautiful NOT Mind)
{
"profile": "true"
}
GET /movies/_search?q=title:(Beautiful %2bMind)
{
"profile": "true"
}
GET /movies/_search?q=year:>=1980
{
"profile": "true"
}
# 通配符查询
GET /movies/_search?q=title:b*
{
"profile": "true"
}
# 模糊匹配&近似度匹配
GET /movies/_search?q=title:beautifl~1
{
"profile": "true"
}
# 模糊匹配&近似度匹配
GET /movies/_search?q=title:"Lord Rings"~2
{
"profile": "true"
}
Request Body查询
-
支持
POST和GET -
需要指定操作索引名
-
需要执行的操作类型
-
指定操作类型
-
分页
-
From从0开始,默认返回10个结果
-
获取靠后的翻页成本较高
-
-
排序
-
最好在
数字型与日期型字段上排序 -
因为对于多值类型或分析过的字段排序,系统会选定一个,无法的值该值
-
-
_source filtering
-
如果_source没有存储,那就只返回匹配的文档的元数据
-
_source支持使用通配符
-
_source[“name*“, “desc*“]
-
-
-
脚本字段
-
通过自定义执行脚本,返回需要的值
-
-
Match 表达式
-
根据字段查询 :
"comment": "Last Christmas" -
执行
AND查询操作 -
短语搜索 –
Match Phrase
-
curl -XGET
"http://localhost:9200/movies/_search" -H
'Content-type:application/json' -d
'{
"form": 10, // 分页参数
"size": 20,
"sort": [{"order_date":"desc"}],
"_source": ["order_date", "order_date", "category.keyword"]
"query": {
"match_all": {} // 匹配所有
"match": {
"comment": "Last Christmas"
},
"match": {
"comment": {
"query": "Last Christmas",
"operator": "AND"
}
},
"match_phrase": { // 短语搜索
"comment": {
"query": "Song Last Christmas",
"slop": "1" // 中间可以有其他的字符
}
}
},
"script_fields":{
"new_field": {
"script": {
"lang": "painless",
"source": "doc['order_date'].value + 'hello'"
}
}
}
}'
执行实例
# 对日期排序
POST kibana_sample_data_ecommerce/_search
{
"sort": [{"order_date": "desc"}],
"query": {
"match_all": {}
}
}
# source filtering
POST kibana_sample_data_ecommerce/_search
{
"sort": [{"order_date": "desc"}],
"_source": ["order_date"],
"query": {
"match_all": {}
}
}
# source filtering
POST kibana_sample_data_ecommerce/_search
{
"sort": [{"order_date": "desc"}],
"_source": ["order_date"],
"query": {
"match_all": {}
}
}
# 脚本字段
POST kibana_sample_data_ecommerce/_search
{
"sort": [{"order_date": "desc"}],
"_source": ["order_date"],
"query": {
"match_all": {}
},
"script_fields":{
"new_field": {
"script": {
"lang": "painless",
"source": "doc['order_date'].value + '_hello'"
}
}
}
}
# 匹配Or关系
POST movies/_search
{
"query": {
"match": {
"title": "Last Christmas"
}
}
}
# 匹配AND关系
POST movies/_search
{
"query": {
"match": {
"title": {
"query": "Last Christmas",
"operator": "and"
}
}
}
}
POST movies/_search
{
"query": {
"match_phrase": {
"title": {
"query": "one love"
}
}
}
}
POST movies/_search
{
"query": {
"match_phrase": {
"title": {
"query": "one love",
"slop": 1
}
}
}
}
响应对象
{
"took" : 4, // 花费时间
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 10000, // 符合条件的文档总数
"relation" : "gte"
},
"max_score" : 1.0,
"hits" : [ // 结果集
{
"_index" : "movies", // 索引名
"_type" : "_doc",
"_id" : "2716", // 文档ID
"_score" : 1.0, //相关度评分
"_source" : { // 原始文档信息
"title" : "Ghostbusters",
"id" : "2716",
"@version" : "1",
"genre" : [
"Action",
"Comedy",
"Sci-Fi"
],
"year" : 0
}
},
{
"_index" : "movies",
"_type" : "_doc",
"_id" : "2717",
"_score" : 1.0,
"_source" : {
"title" : "Ghostbusters II",
"id" : "2717",
"@version" : "1",
"genre" : [
"Comedy",
"Fantasy",
"Sci-Fi"
],
"year" : 1989
}
},
{
"_index" : "movies",
"_type" : "_doc",
"_id" : "2718",
"_score" : 1.0,
"_source" : {
"title" : "Drop Dead Gorgeous",
"id" : "2718",
"@version" : "1",
"genre" : [
"Comedy"
],
"year" : 1999
}
},
{
"_index" : "movies",
"_type" : "_doc",
"_id" : "2719",
"_score" : 1.0,
"_source" : {
"title" : "Haunting, The",
"id" : "2719",
"@version" : "1",
"genre" : [
"Horror",
"Thriller"
],
"year" : 1999
}
},
{
"_index" : "movies",
"_type" : "_doc",
"_id" : "2720",
"_score" : 1.0,
"_source" : {
"title" : "Inspector Gadget",
"id" : "2720",
"@version" : "1",
"genre" : [
"Action",
"Adventure",
"Children",
"Comedy"
],
"year" : 1999
}
},
{
"_index" : "movies",
"_type" : "_doc",
"_id" : "2721",
"_score" : 1.0,
"_source" : {
"title" : "Trick",
"id" : "2721",
"@version" : "1",
"genre" : [
"Comedy",
"Romance"
],
"year" : 1999
}
},
{
"_index" : "movies",
"_type" : "_doc",
"_id" : "2722",
"_score" : 1.0,
"_source" : {
"title" : "Deep Blue Sea",
"id" : "2722",
"@version" : "1",
"genre" : [
"Action",
"Horror",
"Sci-Fi",
"Thriller"
],
"year" : 1999
}
},
{
"_index" : "movies",
"_type" : "_doc",
"_id" : "2723",
"_score" : 1.0,
"_source" : {
"title" : "Mystery Men",
"id" : "2723",
"@version" : "1",
"genre" : [
"Action",
"Comedy",
"Fantasy"
],
"year" : 1999
}
},
{
"_index" : "movies",
"_type" : "_doc",
"_id" : "2724",
"_score" : 1.0,
"_source" : {
"title" : "Runaway Bride",
"id" : "2724",
"@version" : "1",
"genre" : [
"Comedy",
"Romance"
],
"year" : 1999
}
},
{
"_index" : "movies",
"_type" : "_doc",
"_id" : "2725",
"_score" : 1.0,
"_source" : {
"title" : "Twin Falls Idaho",
"id" : "2725",
"@version" : "1",
"genre" : [
"Drama"
],
"year" : 1999
}
}
]
}
}
Query String Query
-
类似Query String, 但是会忽略错误的语法,同事支持部分查询语法
-
Simple Query
-
不支持 AND, OR, NOT , 会当做字符串处理
-
Term 之间默认关系是
OR, 可以指定Operator -
支持部分逻辑
-
+替代AND -
|替代OR -
-替代NOT
-
-
POST movies/_search
{
"query": {
"query_string": {
"default_field": "name",
"query":"Bob And Liu"
}
}
}
POST movies/_search
{
"query": {
"query_string": {
"fields": ["name", "about"],
"query":"(Bob And Liu) OR (Java AND Elasticsearch)"
}
}
}
PUT /users/_doc/2
{
"name": "Bob Liu",
"about": "Hadoop"
}
POST /users/_search
{
"query": {
"query_string": {
"default_field": "name",
"query": "Bob AND Liu"
}
}
}
POST /users/_search
{
"query": {
"query_string": {
"default_field": "name",
"query": "(Bob AND Liu) OR (Java AND Elasticsearch)"
}
}
}
# Simple Query 默认的operator 是 Or
POST /users/_search
{
"query": {
"simple_query_string": {
"fields": ["name"],
"query": "Bob AND Liu"
}
}
}
POST /users/_search
{
"query": {
"simple_query_string": { // simple 处理方式不一行
"fields": ["name"],
"query": "Bob Liu",
"default_operator": "AND"
}
}
}
搜索相关性
-
搜索是用户和搜索引擎的对话
-
用户关心的是搜索结果的相关性
-
是否可以找到相关所有的内容
-
返回不相关内容的数量
-
文档打分是否合理
-
-