目录
- 查询文档 & 基本操作
- 查询文档 & 条件查询
- 不附加任何条件
- 相关字段解释
- 基础分页查询
- url参数
- body 参数
- 单字段全文索引查询
- 单字段不分词查询
- match分词结果
- match_phrase 不分词查询结果
- 多字段全文索引查询
- 范围查询
- 单字段精确查询
- 字段精确查询 & 多值
- 文档包含字段查询
- 结束语
查询文档 & 基本操作
为了方便学习, 本节中所有示例沿用上节的索引
按照ID单个
GET class_1/_doc/1
查询结果:
{ \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"1\", \"_version\" : 4, \"_seq_no\" : 4, \"_primary_term\" : 3, \"found\" : true, \"_source\" : { \"name\" : \"l\", \"num\" : 6 } }
按照ID批量
GET class_1/_mget { \"ids\":[1,2,3] }
返回:
{ \"docs\" : [ { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"1\", \"_version\" : 4, \"_seq_no\" : 4, \"_primary_term\" : 3, \"found\" : true, \"_source\" : { \"name\" : \"l\", \"num\" : 6 } }, { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"2\", \"found\" : false }, { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"3\", \"_version\" : 3, \"_seq_no\" : 10, \"_primary_term\" : 4, \"found\" : true, \"_source\" : { \"num\" : 9, \"name\" : \"e\", \"age\" : 9, \"desc\" : [ \"hhhh\" ] } } ] }
查询文档是否存在 & 通过id判断
HEAD class_1/_doc/1
返回:
200 - OK
HEAD class_1/_doc/1000
返回:
404 - Not Found
查询部分字段内容
GET class_1/_doc/1?_source_includes=name
返回:
{ \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"1\", \"_version\" : 4, \"_seq_no\" : 4, \"_primary_term\" : 3, \"found\" : true, \"_source\" : { \"name\" : \"l\" } }
可以看到只返回了name
字段, 以上是一个基本的操作,下面给大家讲下条件查询~
查询文档 & 条件查询
查询的复杂度取决于它附加的条件约束,跟我们写sql
一样。下面就带大家一步一步看一下ES
中如何进行条件查询~
不附加任何条件
GET class_1/_search
返回:
{ \"took\" : 15, \"timed_out\" : false, \"_shards\" : { \"total\" : 3, \"successful\" : 3, \"skipped\" : 0, \"failed\" : 0 }, \"hits\" : { \"total\" : { \"value\" : 8, \"relation\" : \"eq\" }, \"max_score\" : 1.0, \"hits\" : [ { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"h2Fg-4UBECmbBdQA6VLg\", \"_score\" : 1.0, \"_source\" : { \"name\" : \"b\", \"num\" : 6 } }, { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"iGFt-4UBECmbBdQAnVJe\", \"_score\" : 1.0, \"_source\" : { \"name\" : \"g\", \"age\" : 8 } }, { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"iWFt-4UBECmbBdQAnVJg\", \"_score\" : 1.0, \"_source\" : { \"name\" : \"h\", \"age\" : 9 } }, { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"imFt-4UBECmbBdQAnVJg\", \"_score\" : 1.0, \"_source\" : { \"name\" : \"i\", \"age\" : 10 } }, { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"3\", \"_score\" : 1.0, \"_source\" : { \"num\" : 9, \"name\" : \"e\", \"age\" : 9, \"desc\" : [ \"hhhh\" ] } }, { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"4\", \"_score\" : 1.0, \"_source\" : { \"name\" : \"f\", \"age\" : 10, \"num\" : 10 } }, { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"RWlfBIUBDuA8yW5cu9wu\", \"_score\" : 1.0, \"_source\" : { \"name\" : \"一年级\", \"num\" : 20 } }, { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"1\", \"_score\" : 1.0, \"_source\" : { \"name\" : \"l\", \"num\" : 6 } } ] } }
可以看到索引class_1
中的所有数据都是上节添加的。这里提一下,我们也可以添加多个索引一起查,然后返回,用,逗号
隔开就可以了
GET class_1,class_2,class_3/_search
{ \"took\" : 7, \"timed_out\" : false, \"_shards\" : { \"total\" : 5, \"successful\" : 5, \"skipped\" : 0, \"failed\" : 0 }, \"hits\" : { \"total\" : { \"value\" : 9, \"relation\" : \"eq\" }, \"max_score\" : 1.0, \"hits\" : [ { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"h2Fg-4UBECmbBdQA6VLg\", \"_score\" : 1.0, \"_source\" : { \"name\" : \"b\", \"num\" : 6 } }, { \"_index\" : \"class_2\", \"_type\" : \"_doc\", \"_id\" : \"RWlfBIUBDuA8yW5cu9wu\", \"_score\" : 1.0, \"_source\" : { \"name\" : \"一年级\", \"num\" : 20 } }, .... ] } }
可以看到返回了索引class_2
中的数据,并且合并到了一起。
相关字段解释
有的小伙伴可能对返回的字段有点陌生,这里给大家统一解释一下:
{ \"took\":\"查询操作耗时,单位毫秒\", \"timed_out\":\"是否超时\", \"_shards\":{ \"total\":\"分片总数\", \"successful\":\"执行成功分片数\", \"skipped\":\"执行忽略分片数\", \"failed\":\"执行失败分片数\" }, \"hits\":{ \"total\":{ \"value\":\"条件查询命中数\", \"relation\":\"计数规则(eq计数准确/gte计数不准确)\" }, \"max_score\":\"最大匹配度分值\", \"hits\":[ { \"_index\":\"命中结果索引\", \"_id\":\"命中结果ID\", \"_score\":\"命中结果分数\", \"_source\":\"命中结果原文档信息\" } ] } }
下面我们看下带条件的查询~
基础分页查询
基本语法: es
中通过参数size
和from
来进行基础分页
的控制
from
:指定跳过
多少条数据size
:指定返回
多少条数据
下面看下示例:
url参数
GET class_1/_search?from=2&size=2
返回:
{ \"took\" : 5, \"timed_out\" : false, \"_shards\" : { \"total\" : 3, \"successful\" : 3, \"skipped\" : 0, \"failed\" : 0 }, \"hits\" : { \"total\" : { \"value\" : 8, \"relation\" : \"eq\" }, \"max_score\" : 1.0, \"hits\" : [ { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"iWFt-4UBECmbBdQAnVJg\", \"_score\" : 1.0, \"_source\" : { \"name\" : \"h\", \"age\" : 9 } }, { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"imFt-4UBECmbBdQAnVJg\", \"_score\" : 1.0, \"_source\" : { \"name\" : \"i\", \"age\" : 10 } } ] } }
body 参数
GET class_1/_search { \"from\" : 2, \"size\" : 2 }
返回结果和上面是一样的~
单字段全文索引查询
这个大家应该不陌生,前面几节都见过。使用query.match
进行查询,match
适用与对单个字段基于全文索引进行数据检索。对于全文字段,match
使用特定的分词
进行全文检索。而对于那些精确值,match
同样可以进行精确匹配,match
查询短语时,会对短语进行分词,再针对每个词条进行全文检索。
GET class_1/_search { \"query\": { \"match\": { \"name\":\"i\" } } }
返回:
{ \"took\" : 4, \"timed_out\" : false, \"_shards\" : { \"total\" : 3, \"successful\" : 3, \"skipped\" : 0, \"failed\" : 0 }, \"hits\" : { \"total\" : { \"value\" : 1, \"relation\" : \"eq\" }, \"max_score\" : 1.3862942, \"hits\" : [ { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"imFt-4UBECmbBdQAnVJg\", \"_score\" : 1.3862942, \"_source\" : { \"name\" : \"i\", \"age\" : 10 } } ] } }
单字段不分词查询
使用query.match_phrase
进行查询, 它与match
的区别就是不进行分词,干说,可能有点抽象,下面我们通过一个例子给大家分清楚:
先造点数据进去:
PUT class_1/_bulk { \"create\":{ } } {\"name\":\"I eat apple so haochi1~\",\"num\": 1} { \"create\":{ } } { \"name\":\"I eat apple so zhen haochi2~\",\"num\": 1} { \"create\":{ } } {\"name\":\"I eat apple so haochi3~\",\"num\": 1}
假设有这么几个句子,现在我有一个需求我要把I eat apple so zhen haochi2~
这句话匹配出来
match分词结果
GET class_1/_search { \"query\": { \"match\": { \"name\": \"apple so zhen\" } } }
返回:
{ \"took\" : 15, \"timed_out\" : false, \"_shards\" : { \"total\" : 3, \"successful\" : 3, \"skipped\" : 0, \"failed\" : 0 }, \"hits\" : { \"total\" : { \"value\" : 3, \"relation\" : \"eq\" }, \"max_score\" : 2.2169428, \"hits\" : [ { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"cMfcCoYB090miyjed7YE\", \"_score\" : 2.2169428, \"_source\" : { \"name\" : \"I eat apple so zhen haochi2~\", \"num\" : 1 } }, { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"b8fcCoYB090miyjed7YE\", \"_score\" : 1.505254, \"_source\" : { \"name\" : \"I eat apple so haochi1~\", \"num\" : 1 } }, { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"ccfcCoYB090miyjed7YE\", \"_score\" : 1.505254, \"_source\" : { \"name\" : \"I eat apple so haochi3~\", \"num\" : 1 } } ] } }
从结果来看,刚刚的几句话都被查出来了,但是结果并大符合预期。从score
来看,"_score" : 2.2169428
得分最高,排在了第一,语句是I eat apple so zhen haochi2~
,说明匹配度最高,这个句子正是我们想要的结果~
match_phrase 不分词查询结果
GET class_1/_search { \"query\": { \"match_phrase\": { \"name\": \"apple so zhen\" } } }
结果:
{ \"took\" : 6, \"timed_out\" : false, \"_shards\" : { \"total\" : 3, \"successful\" : 3, \"skipped\" : 0, \"failed\" : 0 }, \"hits\" : { \"total\" : { \"value\" : 1, \"relation\" : \"eq\" }, \"max_score\" : 2.2169428, \"hits\" : [ { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"cMfcCoYB090miyjed7YE\", \"_score\" : 2.2169428, \"_source\" : { \"name\" : \"I eat apple so zhen haochi2~\", \"num\" : 1 } } ] } }
结果符合预期,只返回了我们想要的那句。那么match
为什么都返回了,这就是前面讲到的分词
,首先会对name: apple so zhen
进行分词,也就是说存在apple
的都会被返回。
当然,真正业务中的需求比这个复杂多了,这里只是为了给大家做区分~ 下面接着看~
多字段全文索引查询
相当于对多个字段执行了match
查询, 这里需要注意的是query
的类型要和字段类型一致,不然会报类型异常
GET class_1/_search { \"query\": { \"multi_match\": { \"query\": \"apple\", \"fields\": [\"name\",\"desc\"] } } }
{ \"took\" : 5, \"timed_out\" : false, \"_shards\" : { \"total\" : 3, \"successful\" : 3, \"skipped\" : 0, \"failed\" : 0 }, \"hits\" : { \"total\" : { \"value\" : 3, \"relation\" : \"eq\" }, \"max_score\" : 0.752627, \"hits\" : [ { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"b8fcCoYB090miyjed7YE\", \"_score\" : 0.752627, \"_source\" : { \"name\" : \"I eat apple so haochi1~\", \"num\" : 1 } }, { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"ccfcCoYB090miyjed7YE\", \"_score\" : 0.752627, \"_source\" : { \"name\" : \"I eat apple so haochi3~\", \"num\" : 1 } }, { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"cMfcCoYB090miyjed7YE\", \"_score\" : 0.7389809, \"_source\" : { \"name\" : \"I eat apple so zhen haochi2~\", \"num\" : 1 } } ] } }
范围查询
使用range
来进行范围查询,适用于数组
,时间
等字段
GET class_1/_search { \"query\": { \"range\": { \"num\": { \"gt\": 5, \"lt\": 10 } } } }
返回:
{ \"took\" : 6, \"timed_out\" : false, \"_shards\" : { \"total\" : 3, \"successful\" : 3, \"skipped\" : 0, \"failed\" : 0 }, \"hits\" : { \"total\" : { \"value\" : 3, \"relation\" : \"eq\" }, \"max_score\" : 1.0, \"hits\" : [ { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"h2Fg-4UBECmbBdQA6VLg\", \"_score\" : 1.0, \"_source\" : { \"name\" : \"b\", \"num\" : 6 } }, { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"3\", \"_score\" : 1.0, \"_source\" : { \"num\" : 9, \"name\" : \"e\", \"age\" : 9, \"desc\" : [ \"hhhh\" ] } }, { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"1\", \"_score\" : 1.0, \"_source\" : { \"name\" : \"l\", \"num\" : 6 } } ] } }
单字段精确查询
使用term
进行非分词字段
的精确查询。需要注意的是,对于那些分词的字段,即使查询的value
是一个完全匹配的短语,也无法完成查询
GET class_1/_search { \"query\": { \"term\": { \"num\": { \"value\": \"9\" } } } }
返回:
{ \"took\" : 4, \"timed_out\" : false, \"_shards\" : { \"total\" : 3, \"successful\" : 3, \"skipped\" : 0, \"failed\" : 0 }, \"hits\" : { \"total\" : { \"value\" : 1, \"relation\" : \"eq\" }, \"max_score\" : 1.0, \"hits\" : [ { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"3\", \"_score\" : 1.0, \"_source\" : { \"num\" : 9, \"name\" : \"e\", \"age\" : 9, \"desc\" : [ \"hhhh\" ] } } ] } }
字段精确查询 & 多值
与term一样, 区别在于可以匹配一个字段的多个值,满足一个即检索成功
GET class_1/_search { \"query\": { \"terms\": { \"num\": [ 9, 1 ] } } }
返回:
{ \"took\" : 8, \"timed_out\" : false, \"_shards\" : { \"total\" : 3, \"successful\" : 3, \"skipped\" : 0, \"failed\" : 0 }, \"hits\" : { \"total\" : { \"value\" : 4, \"relation\" : \"eq\" }, \"max_score\" : 1.0, \"hits\" : [ { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"3\", \"_score\" : 1.0, \"_source\" : { \"num\" : 9, \"name\" : \"e\", \"age\" : 9, \"desc\" : [ \"hhhh\" ] } }, { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"b8fcCoYB090miyjed7YE\", \"_score\" : 1.0, \"_source\" : { \"name\" : \"I eat apple so haochi1~\", \"num\" : 1 } }, { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"ccfcCoYB090miyjed7YE\", \"_score\" : 1.0, \"_source\" : { \"name\" : \"I eat apple so haochi3~\", \"num\" : 1 } }, { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"cMfcCoYB090miyjed7YE\", \"_score\" : 1.0, \"_source\" : { \"name\" : \"I eat apple so zhen haochi2~\", \"num\" : 1 } } ] } }
文档包含字段查询
为了确定当前索引有哪些文档包含了对应的字段,es
中使用exists
来实现
GET class_1/_search { \"query\": { \"exists\": { \"field\": \"desc\" } } }
返回:
{ \"took\" : 8, \"timed_out\" : false, \"_shards\" : { \"total\" : 3, \"successful\" : 3, \"skipped\" : 0, \"failed\" : 0 }, \"hits\" : { \"total\" : { \"value\" : 1, \"relation\" : \"eq\" }, \"max_score\" : 1.0, \"hits\" : [ { \"_index\" : \"class_1\", \"_type\" : \"_doc\", \"_id\" : \"3\", \"_score\" : 1.0, \"_source\" : { \"num\" : 9, \"name\" : \"e\", \"age\" : 9, \"desc\" : [ \"hhhh\" ] } } ] } }
结束语
本节主要讲了ES
中的文档查询API操作,该部分内容较多, 下节继续给大家讲,就先消化这么多~API
大家都不要去背,多敲几遍就记住了,关键是多用,多总结 。
以上就是ElasticSearch查询文档基本操作实例的详细内容,更多关于ElasticSearch查询文档的资料请关注其它相关文章!
做猪小侠源码的代理,提供一站式服务
如果你不懂得搭建网站或者服务器,小程序,源码之类的怎么办? 第一通过本站学习各种互联网的技术 第二就是联系客服,我帮帮你搭建(当然要收取部分的费用) 第三成为我们的代理,我们提供整套的服务。