关键字 含义 类比SQL
query 查询 select
bool 多个组合条件 selext xxx from xxx where age=20 and gender=male
filter 一个过滤条件 where
term 精确匹配 =
match 全文检索,会分词
must 在过滤条件中使用,代表必须包含
fuzzy 模糊匹配 dick 联想到 nick pick
from 从哪一条开始取
size 取多少条 limit
_source 只选择某些字段 select 字段
match_phrase 短语匹配,将输入的查询内容整个作为整体进行查询,不切词
multi_match 一次到多个子弹中匹配内容 or

检索

全文检索

select * from stu;

  1. # 协议方法 索引/类型/_search
  2. GET stu/_search

字段全值匹配检索

检索前提:如果是语句,那么会将语句分为词,我们的sql过滤条件就只能是切词,而不能是语句,因为索引只存切开的词,不存整条语句

这里的全值就是字面意思,意思是去匹配整个词i love you
而i love you在索引中是不存在的

  1. GET /test02/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "filter": {
  6. "term": {
  7. "name": "i love you"
  8. }
  9. }
  10. }
  11. }
  12. }
  13. 查询结果:
  14. {
  15. "took" : 0,
  16. "timed_out" : false,
  17. "_shards" : {
  18. "total" : 1,
  19. "successful" : 1,
  20. "skipped" : 0,
  21. "failed" : 0
  22. },
  23. "hits" : {
  24. "total" : {
  25. "value" : 0,
  26. "relation" : "eq"
  27. },
  28. "max_score" : null,
  29. "hits" : [ ]
  30. }
  31. }
  32. 没有对应的查询条件,因为ik_max_word分词器会把“i love you”分成以下词组
  33. i loveyou
  34. 我们会发现并没有“i love you”这几个字组合起来的词,因此查不到。
  35. 写条件的时候只能写:
  36. GET /test02/_search
  37. {
  38. "query": {
  39. "bool": {
  40. "filter": {
  41. "term": {
  42. "name": "love" (或iyou
  43. }
  44. }
  45. }
  46. }
  47. }

第二种:match_phrase 搜索
既可以匹配分词又能匹配整个i love you
https://juejin.cn/post/6992593362675040292

字段分词匹配检索

这里分词也是字面意思,将i love you拆开,i匹配上了, love也匹配上了,you也匹配上了,所以比分相对比较高

  1. GET test02/_search
  2. {
  3. "query": {
  4. "match": {
  5. "name": "i love you"
  6. }
  7. }
  8. }
  9. (也会拆词,但是也能匹配整条 i love you
  10. 结果展示:
  11. {
  12. "took" : 1,
  13. "timed_out" : false,
  14. "_shards" : {
  15. "total" : 1,
  16. "successful" : 1,
  17. "skipped" : 0,
  18. "failed" : 0
  19. },
  20. "hits" : {
  21. "total" : {
  22. "value" : 1,
  23. "relation" : "eq"
  24. },
  25. "max_score" : 2.2169428,
  26. "hits" : [
  27. {
  28. "_index" : "test02",
  29. "_id" : "pAAMiH8BRK4hWm3D8TBD",
  30. "_score" : 2.2169428,
  31. "_source" : {
  32. "id" : "004",
  33. "name" : "i love you"
  34. }
  35. }
  36. ]
  37. }
  38. }

两者结合使用
比较特别的地方:must关键字

  1. GET student/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "filter": {
  6. "term": {
  7. "sex": "male"
  8. }
  9. }
  10. , "must": [
  11. {
  12. "match": {
  13. "favo": "海狗人参丸"
  14. }
  15. }
  16. ]
  17. }
  18. }
  19. }

字段模糊匹配检索

相当智能
查ffmale,可以模糊匹配出female

  1. GET student/_search
  2. {
  3. "query": {
  4. "fuzzy": {
  5. "sex": "ffmale" ffmale,可以模糊匹配出female
  6. }
  7. }
  8. }

[

](https://juejin.cn/post/6992593362675040292)

分页检索

  1. GET student/_search
  2. {
  3. "from": 0, (从第几条开始)
  4. "size": 1 (显示几条)
  5. }

聚合

1.结构

  1. aggregations|aggs
  2. "aggregations" :
  3. {
  4. --aggregation_name:聚合字段名
  5. "<aggregation_name>" :
  6. {
  7. --聚合运算的类型,类比,sum,avg,count(Term),min,max sum()
  8. "<aggregation_type>" :
  9. {
  10. --num 对什么字段进行聚合
  11. <aggregation_body>
  12. }
  13. -- 对哪些表进行聚合,类比tablea,不写,将meta写在url
  14. [,"meta" : { [<meta_data_body>] } ]?
  15. --子聚合,在当前聚合的基础上,继续聚合
  16. [,"aggregations" : { [<sub_aggregation>]+ } ]?
  17. }
  18. --
  19. [,"<aggregation_name_2>" : { ... } ]*
  20. }
  21. count 等价于 term
  22. count(*) ======== sum(if(gender = 'male',1,0))
  23. select
  24. a,max(sum_num) --子聚合
  25. from
  26. (select
  27. a,b,sum(num) sum_nummax(num) max_num
  28. from tablea
  29. where xxx
  30. group by a,b) tmp
  31. group by a

2.聚合报错

“type”: “illegal_argument_exception”,
“reason”: “Fielddata is disabled on text fields by default. Set fielddata=true on [gender] in order to load fielddata in memory by uninverting the inverted index.

Note that this can however use significant memory. Alternatively use a keyword field instead.”

TEXT类型,因为涉及到分词,无法被聚合!

解决: 使用KEYWORD类型


a_column(text)
中国人 ———> 中国,国人,中国人

3.聚合练习

  1. #13.聚合之单聚合,统计男女员工各多少人
  2. GET /test/emps/_search
  3. {
  4. "query": {
  5. "match_all": {}
  6. },
  7. "aggs": {
  8. "gendercount": {
  9. "terms": {
  10. "field": "gender.keyword",
  11. "size": 10
  12. }
  13. }
  14. }
  15. }
  16. #14.聚合之先查询再聚合,统计喜欢购物的男女员工各多少人
  17. GET /test/emps/_search
  18. {
  19. "query": {
  20. "match": {
  21. "hobby": "购物"
  22. }
  23. },
  24. "aggs": {
  25. "gendercount": {
  26. "terms": {
  27. "field": "gender.keyword",
  28. "size": 10
  29. }
  30. }
  31. }
  32. }
  33. #15.聚合之多聚合,统计喜欢购物的男女员工各多少人,及这些人总体的平均年龄
  34. GET /test/emps/_search
  35. {
  36. "query": {
  37. "match": {
  38. "hobby": "购物"
  39. }
  40. },
  41. "aggs": {
  42. "gendercount": {
  43. "terms": {
  44. "field": "gender.keyword",
  45. "size": 10
  46. }
  47. },
  48. "avgage":{
  49. "avg": {
  50. "field": "age"
  51. }
  52. }
  53. }
  54. }
  55. #16.聚合之多聚合和嵌套聚合,统计喜欢购物的男女员工各多少人,及这些人不同性别的平均年龄
  56. GET /test/emps/_search
  57. {
  58. "query": {
  59. "match": {
  60. "hobby": "购物"
  61. }
  62. },
  63. "aggs": {
  64. "gendercount": {
  65. "terms": {
  66. "field": "gender.keyword",
  67. "size": 10
  68. },
  69. "aggs": {
  70. "avgage": {
  71. "avg": {
  72. "field": "age"
  73. }
  74. }
  75. }
  76. }
  77. }
  78. }

综合练习

  1. #0.查询的两种方式
  2. # 查询方式一发送REST请求的方式 将请求参数附加在url的后面
  3. GET /test/emps/_search
  4. GET /test/emps/_search?q=*
  5. GET /test/emps/_search?q=age:22
  6. #查询22岁的员工,且按照balance降序排序
  7. GET /test/emps/_search?q=age:22&sort=balance:desc
  8. # 查询方式二,使用ES DSL(特定领域语言)语法 ,将请求参数附加在请求体中
  9. GET /test/emps/_search
  10. {
  11. "query": {
  12. "match_all": {}
  13. }
  14. }
  15. #1.全表查询
  16. #2.全表查询,按照年龄降序排序,再按照工资降序排序,只取前5条记录的示empidagebalance
  17. GET /test/emps/_search
  18. {
  19. "sort": [
  20. {
  21. "age": {
  22. "order": "desc"
  23. }
  24. },
  25. {
  26. "balance": {
  27. "order": "desc"
  28. }
  29. }
  30. ],
  31. "from": 0,
  32. "size": 5,
  33. "_source": [
  34. "empid",
  35. "age",
  36. "balance"
  37. ]
  38. }
  39. #3.匹配之match(全文检索)分词匹配: 搜索hobby含有吃饭睡觉的员工
  40. #原理:先将查询条件切词,切为 吃饭、睡觉,分别从hobby的倒排索引上
  41. #检索吃饭、睡觉
  42. #where hobby like %吃饭% or hobby like %睡觉%
  43. GET /_analyze
  44. {
  45. "analyzer": "ik_max_word",
  46. "text":"吃饭睡觉"
  47. }
  48. GET /test/emps/_search
  49. {
  50. "query": {
  51. "match": {
  52. "hobby": "吃饭睡觉"
  53. }
  54. }
  55. }
  56. #4.匹配之match/term不分词匹配: 搜索工资是2000的员工
  57. # 2000会不会被切词? 不会!只有text类型能被切词,精确匹配
  58. # balance = 2000 而不是 balance like %2000%
  59. # ES中官方建议,在对 text类型进行全文检索时,才用match
  60. # 如果搜索的不是text类型,建议使用term
  61. GET /test/emps/_search
  62. {
  63. "query": {
  64. "match": {
  65. "balance": 2000
  66. }
  67. }
  68. }
  69. # 匹配之term不分词匹配: 搜索工资是2000的员工
  70. GET /test/emps/_search
  71. {
  72. "query": {
  73. "term": {
  74. "balance": 2000
  75. }
  76. }
  77. }
  78. #5.匹配之match不分词匹配: 搜索hobby是吃饭睡觉的员工
  79. # where hobby like %吃饭睡觉%
  80. #keyword类型不切词
  81. GET /test/emps/_search
  82. {
  83. "query": {
  84. "match": {
  85. "hobby.keyword": "吃饭睡觉"
  86. }
  87. }
  88. }
  89. #6.匹配之短语匹配: 搜索hobby是吃饭的员工
  90. GET /test/emps/_search
  91. {
  92. "query": {
  93. "match_phrase": {
  94. "hobby": "吃饭睡觉"
  95. }
  96. }
  97. }
  98. #7.匹配之多字段匹配: 搜索namehobby中带球的员工
  99. GET /test/emps/_search
  100. {
  101. "query": {
  102. "multi_match": {
  103. "query": "球",
  104. "fields": ["name","hobby"]
  105. }
  106. }
  107. }
  108. #8.匹配之多条件匹配,搜索男性中喜欢购物的员工
  109. GET /test/emps/_search
  110. {
  111. "query": {
  112. "bool": {
  113. "must": [
  114. {
  115. "match": {
  116. "hobby": "购物"
  117. }
  118. },
  119. {
  120. "term": {
  121. "gender": {
  122. "value": "男"
  123. }
  124. }
  125. }
  126. ]
  127. }
  128. }
  129. }
  130. #9.匹配之多条件匹配,搜索男性中喜欢购物,还不能爱去酒吧的员工
  131. GET /test/emps/_search
  132. {
  133. "query": {
  134. "bool": {
  135. "must": [
  136. {
  137. "match": {
  138. "hobby": "购物"
  139. }
  140. },
  141. {
  142. "term": {
  143. "gender": {
  144. "value": "男"
  145. }
  146. }
  147. }
  148. ],
  149. "must_not": [
  150. {
  151. "match": {
  152. "hobby": "去酒吧"
  153. }
  154. }
  155. ]
  156. }
  157. }
  158. }
  159. #10.匹配之多条件匹配,搜索男性中喜欢购物,还不能爱去酒吧的员工,最好在20-30之间
  160. #最好在20-30之间: 如果这个人年龄在20-30之间,优先选择!加分!
  161. #should 符合条件就加分
  162. GET /test/emps/_search
  163. {
  164. "query": {
  165. "bool": {
  166. "must": [
  167. {
  168. "match": {
  169. "hobby": "购物"
  170. }
  171. },
  172. {
  173. "term": {
  174. "gender": {
  175. "value": "男"
  176. }
  177. }
  178. }
  179. ],
  180. "must_not": [
  181. {
  182. "match": {
  183. "hobby": "去酒吧"
  184. }
  185. }
  186. ],
  187. "should": [
  188. {
  189. "range": {
  190. "age": {
  191. "gte": 20,
  192. "lte": 30
  193. }
  194. }
  195. }
  196. ]
  197. }
  198. }
  199. }
  200. #11.匹配之多条件匹配,搜索男性中喜欢购物,还不能爱去酒吧的员工,最好在20-30之间,不要40岁以上的
  201. GET /test/emps/_search
  202. {
  203. "query": {
  204. "bool": {
  205. "must": [
  206. {
  207. "match": {
  208. "hobby": "购物"
  209. }
  210. },
  211. {
  212. "term": {
  213. "gender": {
  214. "value": "男"
  215. }
  216. }
  217. }
  218. ],
  219. "must_not": [
  220. {
  221. "match": {
  222. "hobby": "去酒吧"
  223. }
  224. }
  225. ],
  226. "should": [
  227. {
  228. "range": {
  229. "age": {
  230. "gte": 20,
  231. "lte": 30
  232. }
  233. }
  234. }
  235. ],
  236. "filter": {
  237. "range": {
  238. "age": {
  239. "lt": 40
  240. }
  241. }
  242. }
  243. }
  244. }
  245. }
  246. #12.匹配之字段模糊联想匹配,搜索Nick
  247. GET /test/emps/_search
  248. {
  249. "query": {
  250. "fuzzy": {
  251. "name": "Dick"
  252. }
  253. }
  254. }