这部分还未涉及到语言中的API,直接使用API调试工具就可以了

索引

类比到关系型数据库,创建索引等同于创建数据库,下面都以创建**shopping**索引为例

创建

请求地址:[http://127.0.0.1:9200/shopping](http://127.0.0.1:9200/shopping) PUT
响应结果:

  1. {
  2. "acknowledged": true,//响应结果
  3. "shards_acknowledged": true,//分片结果
  4. "index": "shopping"//索引名称
  5. }

在ES中,索引是唯一的,因此如果再次发起请求,则会收到服务器的错误提示:

  1. {
  2. "error": {
  3. "root_cause": [
  4. {
  5. "type": "resource_already_exists_exception",
  6. "reason": "index [shopping/J0WlEhh4R7aDrfIc3AkwWQ] already exists",
  7. "index_uuid": "J0WlEhh4R7aDrfIc3AkwWQ",
  8. "index": "shopping"
  9. }
  10. ],
  11. "type": "resource_already_exists_exception",
  12. "reason": "index [shopping/J0WlEhh4R7aDrfIc3AkwWQ] already exists",
  13. "index_uuid": "J0WlEhh4R7aDrfIc3AkwWQ",
  14. "index": "shopping"
  15. },
  16. "status": 400
  17. }

查询&删除

查看所有索引

请求地址:[http://127.0.0.1:9200/_cat/indices?v](http://127.0.0.1:9200/_cat/indices?v) GET
响应结果:

health status index uuid pri rep docs.count docs.deleted store.size pri.store.size yellow open shopping J0WlEhh4R7aDrfIc3AkwWQ 1 1 0 0 208b 208b

查询单个索引

请求地址:[http://127.0.0.1:9200/shopping](http://127.0.0.1:9200/shopping) GET

  1. {
  2. "shopping": {//索引名
  3. "aliases": {},//别名
  4. "mappings": {},//映射
  5. "settings": {//设置
  6. "index": {//设置 - 索引
  7. "creation_date": "1617861426847",//设置 - 索引 - 创建时间
  8. "number_of_shards": "1",//设置 - 索引 - 主分片数量
  9. "number_of_replicas": "1",//设置 - 索引 - 主分片数量
  10. "uuid": "J0WlEhh4R7aDrfIc3AkwWQ",//设置 - 索引 - 主分片数量
  11. "version": {//设置 - 索引 - 主分片数量
  12. "created": "7080099"
  13. },
  14. "provided_name": "shopping"//设置 - 索引 - 主分片数量
  15. }
  16. }
  17. }
  18. }

删除单个索引

请求地址:[http://127.0.0.1:9200/shopping](http://127.0.0.1:9200/shopping) DELETE
请求结果:

  1. {
  2. "acknowledged": true // 删除成功
  3. }

文档

文档其实就相当于关系型数据库中的每一条记录,但是在ES中,记录的类型是可以不同的

创建文档

请求地址:[http://127.0.0.1:9200/shopping/_doc](http://127.0.0.1:9200/shopping/_doc) POST
请求体中的数据:

  1. {
  2. "title":"小米手机",
  3. "category":"小米",
  4. "images":"http://www.gulixueyuan.com/xm.jpg",
  5. "price":3999.00
  6. }

响应结果:

  1. {
  2. "_index": "shopping",//索引
  3. "_type": "_doc",//类型-文档
  4. "_id": "ANQqsHgBaKNfVnMbhZYU",//唯一标识,可以类比为 MySQL 中的主键,随机生成
  5. "_version": 1,//版本
  6. "result": "created",//结果,这里的 create 表示创建成功
  7. "_shards": {//
  8. "total": 2,//分片 - 总数
  9. "successful": 1,//分片 - 总数
  10. "failed": 0//分片 - 总数
  11. },
  12. "_seq_no": 0,
  13. "_primary_term": 1
  14. }
  • 注意:上述的方法中不能使用PUT请求,而是只能使用POST请求
  • _id就相当于数据库中的主键,作为数据的唯一标识。
    • 默认情况下,如果不指定,那么ES会随机生成一个
    • 如果需要自定义唯一标识,那么就需要在请求的时候进行指定,如:[http://127.0.0.1:9200/shopping/_doc/1](http://127.0.0.1:9200/shopping/_doc/1)
    • 另外,如果指定了唯一标识:ID,那么请求方式可以使用PUT

查询文档

主键查询

请求地址:[http://127.0.0.1:9200/shopping/_doc/1](http://127.0.0.1:9200/shopping/_doc/1) GET
返回结果:

  1. {
  2. "_index": "shopping",
  3. "_type": "_doc",
  4. "_id": "1",
  5. "_version": 1,
  6. "_seq_no": 1,
  7. "_primary_term": 1,
  8. "found": true,
  9. "_source": {
  10. "title": "小米手机",
  11. "category": "小米",
  12. "images": "http://www.gulixueyuan.com/xm.jpg",
  13. "price": 3999
  14. }
  15. }

如果是查找不存在的内容,ES服务器则会返回found: false

  1. {
  2. "_index": "shopping",
  3. "_type": "_doc",
  4. "_id": "1001",
  5. "found": false
  6. }

查询所有数据

  1. {
  2. "took": 133,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 2,
  13. "relation": "eq"
  14. },
  15. "max_score": 1,
  16. "hits": [
  17. {
  18. "_index": "shopping",
  19. "_type": "_doc",
  20. "_id": "ANQqsHgBaKNfVnMbhZYU",
  21. "_score": 1,
  22. "_source": {
  23. "title": "小米手机",
  24. "category": "小米",
  25. "images": "http://www.gulixueyuan.com/xm.jpg",
  26. "price": 3999
  27. }
  28. },
  29. {
  30. "_index": "shopping",
  31. "_type": "_doc",
  32. "_id": "1",
  33. "_score": 1,
  34. "_source": {
  35. "title": "小米手机",
  36. "category": "小米",
  37. "images": "http://www.gulixueyuan.com/xm.jpg",
  38. "price": 3999
  39. }
  40. }
  41. ]
  42. }
  43. }

全量修改 & 局部修改 & 删除

全量修改

全量修改就是直接将原有的数据进行覆盖操作

请求地址:[http://127.0.0.1:9200/shopping/_doc/1](http://127.0.0.1:9200/shopping/_doc/1) POST
请求内容:

  1. {
  2. "title":"华为手机",
  3. "category":"华为",
  4. "images":"http://www.gulixueyuan.com/hw.jpg",
  5. "price":1999.00
  6. }

响应结果:

  1. {
  2. "_index": "shopping",
  3. "_type": "_doc",
  4. "_id": "1",
  5. "_version": 2,
  6. "result": "updated",//<-----------updated 表示数据被更新
  7. "_shards": {
  8. "total": 2,
  9. "successful": 1,
  10. "failed": 0
  11. },
  12. "_seq_no": 2,
  13. "_primary_term": 1
  14. }

局部修改

只修改数据中的一部分,而不是使用新数据覆盖原有的数据

请求地址:[http://127.0.0.1:9200/shopping/_update/1](http://127.0.0.1:9200/shopping/_update/1) POST
请求内容:

  1. {
  2. "doc": {
  3. "title":"小米手机",
  4. "category":"小米"
  5. }
  6. }

响应结果:

  1. {
  2. "_index": "shopping",
  3. "_type": "_doc",
  4. "_id": "1",
  5. "_version": 3,
  6. "result": "updated",//<-----------updated 表示数据被更新
  7. "_shards": {
  8. "total": 2,
  9. "successful": 1,
  10. "failed": 0
  11. },
  12. "_seq_no": 3,
  13. "_primary_term": 1
  14. }

更新后的结果:

  1. {
  2. "_index": "shopping",
  3. "_type": "_doc",
  4. "_id": "1",
  5. "_version": 3,
  6. "_seq_no": 3,
  7. "_primary_term": 1,
  8. "found": true,
  9. "_source": {
  10. "title": "小米手机",
  11. "category": "小米",
  12. "images": "http://www.gulixueyuan.com/hw.jpg",
  13. "price": 1999
  14. }
  15. }

局部修改的时候,如果使用到的字段是原本数据中不存在的,那么就会将进行更新操作,添加一个新的字段

删除

删除一个文档并不会直接将其从磁盘上删除,执行的只是逻辑删除操作,只是对文档进行了删除标记

请求地址:[http://127.0.0.1:9200/shopping/_doc/1](http://127.0.0.1:9200/shopping/_doc/1) DELETE
返回结果:

  1. {
  2. "_index": "shopping",
  3. "_type": "_doc",
  4. "_id": "1",
  5. "_version": 4,
  6. "result": "deleted",//<---删除成功
  7. "_shards": {
  8. "total": 2,
  9. "successful": 1,
  10. "failed": 0
  11. },
  12. "_seq_no": 4,
  13. "_primary_term": 1
  14. }

高级查询

条件查询&分页查询&查询排序

现在假设有如下数据:

  1. {
  2. "took": 5,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 6,
  13. "relation": "eq"
  14. },
  15. "max_score": 1,
  16. "hits": [
  17. {
  18. "_index": "shopping",
  19. "_type": "_doc",
  20. "_id": "ANQqsHgBaKNfVnMbhZYU",
  21. "_score": 1,
  22. "_source": {
  23. "title": "小米手机",
  24. "category": "小米",
  25. "images": "http://www.gulixueyuan.com/xm.jpg",
  26. "price": 3999
  27. }
  28. },
  29. {
  30. "_index": "shopping",
  31. "_type": "_doc",
  32. "_id": "A9R5sHgBaKNfVnMb25Ya",
  33. "_score": 1,
  34. "_source": {
  35. "title": "小米手机",
  36. "category": "小米",
  37. "images": "http://www.gulixueyuan.com/xm.jpg",
  38. "price": 1999
  39. }
  40. },
  41. {
  42. "_index": "shopping",
  43. "_type": "_doc",
  44. "_id": "BNR5sHgBaKNfVnMb7pal",
  45. "_score": 1,
  46. "_source": {
  47. "title": "小米手机",
  48. "category": "小米",
  49. "images": "http://www.gulixueyuan.com/xm.jpg",
  50. "price": 1999
  51. }
  52. },
  53. {
  54. "_index": "shopping",
  55. "_type": "_doc",
  56. "_id": "BtR6sHgBaKNfVnMbX5Y5",
  57. "_score": 1,
  58. "_source": {
  59. "title": "华为手机",
  60. "category": "华为",
  61. "images": "http://www.gulixueyuan.com/xm.jpg",
  62. "price": 1999
  63. }
  64. },
  65. {
  66. "_index": "shopping",
  67. "_type": "_doc",
  68. "_id": "B9R6sHgBaKNfVnMbZpZ6",
  69. "_score": 1,
  70. "_source": {
  71. "title": "华为手机",
  72. "category": "华为",
  73. "images": "http://www.gulixueyuan.com/xm.jpg",
  74. "price": 1999
  75. }
  76. },
  77. {
  78. "_index": "shopping",
  79. "_type": "_doc",
  80. "_id": "CdR7sHgBaKNfVnMbsJb9",
  81. "_score": 1,
  82. "_source": {
  83. "title": "华为手机",
  84. "category": "华为",
  85. "images": "http://www.gulixueyuan.com/xm.jpg",
  86. "price": 1999
  87. }
  88. }
  89. ]
  90. }
  91. }

条件查询

URL带参查询

假如现在需要查询category为小米的文档,可向ES服务器发送请求:
请求地址:[http://127.0.0.1:9200/shopping/_search?q=category:](http://127.0.0.1:9200/shopping/_search?q=category:)小米 GET
返回结果:

  1. {
  2. "took": 94,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 3,
  13. "relation": "eq"
  14. },
  15. "max_score": 1.3862942,
  16. "hits": [
  17. {
  18. "_index": "shopping",
  19. "_type": "_doc",
  20. "_id": "ANQqsHgBaKNfVnMbhZYU",
  21. "_score": 1.3862942,
  22. "_source": {
  23. "title": "小米手机",
  24. "category": "小米",
  25. "images": "http://www.gulixueyuan.com/xm.jpg",
  26. "price": 3999
  27. }
  28. },
  29. {
  30. "_index": "shopping",
  31. "_type": "_doc",
  32. "_id": "A9R5sHgBaKNfVnMb25Ya",
  33. "_score": 1.3862942,
  34. "_source": {
  35. "title": "小米手机",
  36. "category": "小米",
  37. "images": "http://www.gulixueyuan.com/xm.jpg",
  38. "price": 1999
  39. }
  40. },
  41. {
  42. "_index": "shopping",
  43. "_type": "_doc",
  44. "_id": "BNR5sHgBaKNfVnMb7pal",
  45. "_score": 1.3862942,
  46. "_source": {
  47. "title": "小米手机",
  48. "category": "小米",
  49. "images": "http://www.gulixueyuan.com/xm.jpg",
  50. "price": 1999
  51. }
  52. }
  53. ]
  54. }
  55. }

并不推荐直接将查询的内容放在路径中,这样对数据不安全,并且很有可能因为中文而出现乱码的情况,为了避免这种情况,我们需要将查询的数据放入请求体中,并使用json格式进行封装

请求体带参查询

需求如上,还是查询category为小米的文档,请求方式如下:
请求地址:[http://127.0.0.1:9200/shopping/_search](http://127.0.0.1:9200/shopping/_search) GET
请求体:

  1. {
  2. "query":{
  3. "match":{
  4. "category":"小米"
  5. }
  6. }
  7. }

最后同样可以得到预期的查询结果

请求体查询所有

JSON数据中的match字段更换成match_all即可
请求地址:[http://127.0.0.1:9200/shopping/_search](http://127.0.0.1:9200/shopping/_search) GET
请求体:

  1. {
  2. "query":{
  3. "match_all":{}
  4. }
  5. }

则可以查询出所有的文档数据

指定数据字段

同数据库中的操作一样,我们有些时候是不需要查询出所有的字段的,因此可以对数据字段进行限制

  1. {
  2. "query":{
  3. "match_all":{}
  4. },
  5. "_source":["title"]
  6. }

这样,最后查询出来的数据中,就只有title字段

  1. "hits": [
  2. {
  3. "_index": "shopping",
  4. "_type": "_doc",
  5. "_id": "ANQqsHgBaKNfVnMbhZYU",
  6. "_score": 1,
  7. "_source": {
  8. "title": "小米手机"
  9. }
  10. },
  11. {
  12. "_index": "shopping",
  13. "_type": "_doc",
  14. "_id": "A9R5sHgBaKNfVnMb25Ya",
  15. "_score": 1,
  16. "_source": {
  17. "title": "小米手机"
  18. }
  19. },
  20. {
  21. "_index": "shopping",
  22. "_type": "_doc",
  23. "_id": "BNR5sHgBaKNfVnMb7pal",
  24. "_score": 1,
  25. "_source": {
  26. "title": "小米手机"
  27. }
  28. },
  29. {
  30. "_index": "shopping",
  31. "_type": "_doc",
  32. "_id": "BtR6sHgBaKNfVnMbX5Y5",
  33. "_score": 1,
  34. "_source": {
  35. "title": "华为手机"
  36. }
  37. },
  38. {
  39. "_index": "shopping",
  40. "_type": "_doc",
  41. "_id": "B9R6sHgBaKNfVnMbZpZ6",
  42. "_score": 1,
  43. "_source": {
  44. "title": "华为手机"
  45. }
  46. },
  47. {
  48. "_index": "shopping",
  49. "_type": "_doc",
  50. "_id": "CdR7sHgBaKNfVnMbsJb9",
  51. "_score": 1,
  52. "_source": {
  53. "title": "华为手机"
  54. }
  55. }
  56. ]

分页查询

在JSON数据体中使用fromsize两个字段来进行设置分页查询

  1. {
  2. "query":{
  3. "match_all":{}
  4. },
  5. "from":0,
  6. "size":2
  7. }

image.png

查询排序

在查询的时候,有时候我们想要查询出来的数据按照某种指定的方式进行排序,比如按照价格,按照创建时间等等,这可以通过在JSON数据中的sort字段来进行设置

假设我们现在需要通过price字段来进行降序排序,那么传输的数据如下所示:

  1. {
  2. "query":{
  3. "match_all":{}
  4. },
  5. "sort":{
  6. "price":{
  7. "order":"desc"
  8. }
  9. }
  10. }

多条件查询&范围查询

多条件查询

在关系型数据库中,我们的SQL语句,查询条件往往也不止一个,在ES中也同样如此
假设我们现在需要查询手机品牌为小米,并且价格为3999元的所有数据,
那么请求体中的JSON数据如下所示:

  1. {
  2. "query":{
  3. "bool":{
  4. "must":[{
  5. "match":{
  6. "category":"小米"
  7. }
  8. },{
  9. "match":{
  10. "price":3999.00
  11. }
  12. }]
  13. }
  14. }
  15. }

must字段表示,我们的查询条件是的关系,也就是需要同时满足后续设定的所有查询条件

而如果我们想要查询出手机品牌为小米或华为的所有数据,很显然这是一种的关系,那么就需要使用should关键字,表示只要满足后续查询条件中的一个即可

  1. {
  2. "query": {
  3. "bool": {
  4. "should": [
  5. {
  6. "match": {
  7. "category": "小米"
  8. }
  9. },
  10. {
  11. "match": {
  12. "category": "华为"
  13. }
  14. }
  15. ]
  16. },
  17. }
  18. }

范围查询

假设现在需要查询出手机品牌为小米或华为,并且价格要大于2000元的所有手机

  1. {
  2. "query": {
  3. "bool": {
  4. "should": [
  5. {
  6. "match": {
  7. "category": "小米"
  8. }
  9. },
  10. {
  11. "match": {
  12. "category": "华为"
  13. }
  14. }
  15. ],
  16. "filter": {
  17. "range": {
  18. "price": {
  19. "gt": 2000
  20. }
  21. }
  22. }
  23. }
  24. }
  25. }

全文检索&完全匹配&高亮查询

全文检索

全文检索的功能类似于搜索引擎,会尽可能的关联所有可能存在关联关系的数据
比如搜索时输入category小华,但是查询出来的结果既有小米也有华为

  1. {
  2. "query":{
  3. "match":{
  4. "category" : "小华"
  5. }
  6. }
  7. }

image.png

完全匹配

完全匹配和全文检索则不同,更类似于数据库中的模糊查询
完全匹配使用的字段是match_phrase,示例如下:

  1. {
  2. "query":{
  3. "match_phrase":{
  4. "category" : "为"
  5. }
  6. }
  7. }
  1. {
  2. "took": 2,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 3,
  13. "relation": "eq"
  14. },
  15. "max_score": 0.6931471,
  16. "hits": [
  17. {
  18. "_index": "shopping",
  19. "_type": "_doc",
  20. "_id": "BtR6sHgBaKNfVnMbX5Y5",
  21. "_score": 0.6931471,
  22. "_source": {
  23. "title": "华为手机",
  24. "category": "华为",
  25. "images": "http://www.gulixueyuan.com/xm.jpg",
  26. "price": 1999
  27. }
  28. },
  29. {
  30. "_index": "shopping",
  31. "_type": "_doc",
  32. "_id": "B9R6sHgBaKNfVnMbZpZ6",
  33. "_score": 0.6931471,
  34. "_source": {
  35. "title": "华为手机",
  36. "category": "华为",
  37. "images": "http://www.gulixueyuan.com/xm.jpg",
  38. "price": 1999
  39. }
  40. },
  41. {
  42. "_index": "shopping",
  43. "_type": "_doc",
  44. "_id": "CdR7sHgBaKNfVnMbsJb9",
  45. "_score": 0.6931471,
  46. "_source": {
  47. "title": "华为手机",
  48. "category": "华为",
  49. "images": "http://www.gulixueyuan.com/xm.jpg",
  50. "price": 1999
  51. }
  52. }
  53. ]
  54. }
  55. }

高亮查询

可以使用highlight字段来表示高亮的字段

  1. {
  2. "query":{
  3. "match_phrase":{
  4. "category" : "为"
  5. }
  6. },
  7. "highlight":{
  8. "fields":{
  9. "category":{}//<----高亮这字段
  10. }
  11. }
  12. }

查询的结果中,就会将设置的字段进行高亮
image.png

聚合查询

聚合查询和数据库中的聚合查询操作(group by)类似,可以对存储的数据进行统计分析,比如取数据中的最大值、平均值等等
比如对上述的数据,按照price字段进行分组操作:

  1. {
  2. "aggs": { //聚合操作
  3. "price_group": { //名称,随意起名
  4. "terms": { //分组
  5. "field": "price" //分组字段
  6. }
  7. }
  8. }
  9. }

返回结果中可能会存在原始数据,但是我们需要的分组后的数据如下所示:
image.png
如果我们不想要获取原始数据,可以在请求时的JSON数据中,使用size字段来进行限制

  1. {
  2. "aggs":{
  3. "price_group":{
  4. "terms":{
  5. "field":"price"
  6. }
  7. }
  8. },
  9. "size":0
  10. }

这样,我们的请求结果中,就只有聚合查询后的数据了
如果是想要查询手机价格的平均值,那么在请求的数据中使用avg字段即可
image.png

映射关系

有了索引库,其实有了数据库
那么后面就需要创建索引库index的映射了,其类似于数据库中的表结构
创建数据库的时候,我们需要知道字段的名称,长度,约束等等;索引库也同样如此,我们需要这个类型下有哪些字段,每个字段有哪些约束信息,这个关系就叫做映射(mapping