ElasticSearch查询文档基本操作实例

Tani ·
更新时间:2024-09-20
· 238 次阅读

目录

查询文档 & 基本操作

按照ID单个

按照ID批量

查询文档是否存在 & 通过id判断

查询部分字段内容

查询文档 & 条件查询

不附加任何条件

相关字段解释

基础分页查询

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中通过参数sizefrom来进行基础分页的控制

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查询文档的资料请关注软件开发网其它相关文章!



elasticsearch

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章