查询文档 & 基本操作
为了方便学习, 本节中所有示例沿用上节的索引
按照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查询文档的资料请关注编程网其它相关文章!