1 search搜索入门

1.1 搜索语法入门

1.1.1 query string search

  • 语法:无条件查询所有
  1. GET /index/_search
  • 示例:
  • 新增数据:
  1. PUT /book/_doc/1
  2. {
  3. "name": "Bootstrap开发",
  4. "description": "Bootstrap是由Twitter推出的一个前台页面开发css框架,是一个非常流行的开发框架,此框架集成了多种页面效果。此开发框架包含了大量的CSS、JS程序代码,可以帮助开发者(尤其是不擅长css页面开发的程序人员)轻松的实现一个css,不受浏览器限制的精美界面css效果。",
  5. "studymodel": "201002",
  6. "price":38.6,
  7. "timestamp":"2019-08-25 19:11:35",
  8. "pic":"group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
  9. "tags": [ "bootstrap", "dev"]
  10. }
  1. PUT /book/_doc/2
  2. {
  3. "name": "java编程思想",
  4. "description": "java语言是世界第一编程语言,在软件开发领域使用人数最多。",
  5. "studymodel": "201001",
  6. "price":68.6,
  7. "timestamp":"2019-08-25 19:11:35",
  8. "pic":"group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
  9. "tags": [ "java", "dev"]
  10. }
  1. PUT /book/_doc/3
  2. {
  3. "name": "spring开发基础",
  4. "description": "spring 在java领域非常流行,java程序员都在用。",
  5. "studymodel": "201001",
  6. "price":88.6,
  7. "timestamp":"2019-08-24 19:11:35",
  8. "pic":"group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
  9. "tags": [ "spring", "java"]
  10. }
  • 无条件查询所有:
  1. GET /book/_search
  • 返回:
  1. {
  2. "took" : 928,
  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.0,
  16. "hits" : [
  17. {
  18. "_index" : "book",
  19. "_type" : "_doc",
  20. "_id" : "1",
  21. "_score" : 1.0,
  22. "_source" : {
  23. "name" : "Bootstrap开发",
  24. "description" : "Bootstrap是由Twitter推出的一个前台页面开发css框架,是一个非常流行的开发框架,此框架集成了多种页面效果。此开发框架包含了大量的CSS、JS程序代码,可以帮助开发者(尤其是不擅长css页面开发的程序人员)轻松的实现一个css,不受浏览器限制的精美界面css效果。",
  25. "studymodel" : "201002",
  26. "price" : 38.6,
  27. "timestamp" : "2019-08-25 19:11:35",
  28. "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
  29. "tags" : [
  30. "bootstrap",
  31. "dev"
  32. ]
  33. }
  34. },
  35. {
  36. "_index" : "book",
  37. "_type" : "_doc",
  38. "_id" : "2",
  39. "_score" : 1.0,
  40. "_source" : {
  41. "name" : "java编程思想",
  42. "description" : "java语言是世界第一编程语言,在软件开发领域使用人数最多。",
  43. "studymodel" : "201001",
  44. "price" : 68.6,
  45. "timestamp" : "2019-08-25 19:11:35",
  46. "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
  47. "tags" : [
  48. "java",
  49. "dev"
  50. ]
  51. }
  52. },
  53. {
  54. "_index" : "book",
  55. "_type" : "_doc",
  56. "_id" : "3",
  57. "_score" : 1.0,
  58. "_source" : {
  59. "name" : "spring开发基础",
  60. "description" : "spring 在java领域非常流行,java程序员都在用。",
  61. "studymodel" : "201001",
  62. "price" : 88.6,
  63. "timestamp" : "2019-08-24 19:11:35",
  64. "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
  65. "tags" : [
  66. "spring",
  67. "java"
  68. ]
  69. }
  70. }
  71. ]
  72. }
  73. }
  • took:耗费了几毫秒。
  • timed_out:是否超时,false表示没有超时,true表示超时了。
  • _shards:到几个分片搜索。
    • successful:成功几个。
    • skipped:跳过几个。
    • failed:失败几个。
  • hits:命中。
    • total:查询结果的数量。
    • max_score:最大分数。socre的含义,就是document对于一个search的相关度的匹配分数,越相关,就越匹配,分数也越高。
    • hits:包含了匹配搜索的document的所有详细数据

1.1.2 传参

  • 语法:
  1. GET /index/_search?q=field:xxx&sort=filed2:desc

类似于SQL:SELECT * FROM emp where field like ‘%xxx%’ order by filed2 desc。

  • 示例:
  • 查询索引book中的name是java的相关数据
  1. GET /book/_search?q=name:java
  • 返回:
  1. {
  2. "took" : 0,
  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" : 1,
  13. "relation" : "eq"
  14. },
  15. "max_score" : 0.9227538,
  16. "hits" : [
  17. {
  18. "_index" : "book",
  19. "_type" : "_doc",
  20. "_id" : "2",
  21. "_score" : 0.9227538,
  22. "_source" : {
  23. "name" : "java编程思想",
  24. "description" : "java语言是世界第一编程语言,在软件开发领域使用人数最多。",
  25. "studymodel" : "201001",
  26. "price" : 68.6,
  27. "timestamp" : "2019-08-25 19:11:35",
  28. "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
  29. "tags" : [
  30. "java",
  31. "dev"
  32. ]
  33. }
  34. }
  35. ]
  36. }
  37. }
  • 示例:
  • 查询索引book根据价格降序
  1. GET /book/_search?sort=price:desc
  • 返回:
  1. {
  2. "took" : 1,
  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" : null,
  16. "hits" : [
  17. {
  18. "_index" : "book",
  19. "_type" : "_doc",
  20. "_id" : "3",
  21. "_score" : null,
  22. "_source" : {
  23. "name" : "spring开发基础",
  24. "description" : "spring 在java领域非常流行,java程序员都在用。",
  25. "studymodel" : "201001",
  26. "price" : 88.6,
  27. "timestamp" : "2019-08-24 19:11:35",
  28. "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
  29. "tags" : [
  30. "spring",
  31. "java"
  32. ]
  33. },
  34. "sort" : [
  35. 88.6
  36. ]
  37. },
  38. {
  39. "_index" : "book",
  40. "_type" : "_doc",
  41. "_id" : "2",
  42. "_score" : null,
  43. "_source" : {
  44. "name" : "java编程思想",
  45. "description" : "java语言是世界第一编程语言,在软件开发领域使用人数最多。",
  46. "studymodel" : "201001",
  47. "price" : 68.6,
  48. "timestamp" : "2019-08-25 19:11:35",
  49. "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
  50. "tags" : [
  51. "java",
  52. "dev"
  53. ]
  54. },
  55. "sort" : [
  56. 68.6
  57. ]
  58. },
  59. {
  60. "_index" : "book",
  61. "_type" : "_doc",
  62. "_id" : "1",
  63. "_score" : null,
  64. "_source" : {
  65. "name" : "Bootstrap开发",
  66. "description" : "Bootstrap是由Twitter推出的一个前台页面开发css框架,是一个非常流行的开发框架,此框架集成了多种页面效果。此开发框架包含了大量的CSS、JS程序代码,可以帮助开发者(尤其是不擅长css页面开发的程序人员)轻松的实现一个css,不受浏览器限制的精美界面css效果。",
  67. "studymodel" : "201002",
  68. "price" : 38.6,
  69. "timestamp" : "2019-08-25 19:11:35",
  70. "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
  71. "tags" : [
  72. "bootstrap",
  73. "dev"
  74. ]
  75. },
  76. "sort" : [
  77. 38.6
  78. ]
  79. }
  80. ]
  81. }
  82. }

1.1.3 timeout超时查询

  • 语法:
  1. GET /index/_search?timeout=10s
  • 示例:超时查询时间为10秒
  1. GET /book/_search?timeout=10s
  • 搜索的时候,请求必定会横跨所有的主分片,当数量太大的时候,搜索完毕,假设每个分配都需要1个小时,那么用户可能会失去耐心,以至于我们丢失业务。
  • timeout机制,用来指定每个分片只能在给定的时间内查询数据,能有几条数据就返回给用户几条数据。
  • 全局设置:在ES的配置文件elasticsearch.yml中配置search.default_search_timeout: 100ms,如果不配置此参数,默认情况下不超时。

1.2 multi-index多索引搜索

1.2.1 multi-index搜索模式

  • multi-index搜索模式:一次性的搜索多个index和多个type下的数据
  • 语法:所有索引下的所有数据都搜索出来(慎用)
  1. GET /_search
  • 语法:指定一个索引,搜索其下的所有数据
  1. GET /index/_search
  • 语法:同时搜索两个及以上索引下的所有数据
  1. GET /index1,index2/_search
  • 语法:按照通配符去匹配多个索引
  1. GET /index*/_search
  • 应用场景:生产环境中的日志log索引是以日期分开的,比如log_to_es_2019-11-11,log_to_es_2019-11-12和log_to_es_2019-11-13。

1.2.2 搜索原理

  • 客户端发送一个搜索请求,会把请求发送到所有的主分片上进行查询。因为每个主分片上都有一部分数据,每个主分片可以同时搜索;在有副本分片的情况下,会将请求发送到对应的副本分片上进行搜索。

1.3 分页搜索

1.3.1 分页搜索语法

  • 语法:类似于MySQL中的SELECT * FROM book limit 0,10
  1. GET /index/_search?from=0&size=10
  • 示例:
  1. GET /book/_search?from=0&size=3
  • 示例:
  1. GET /book/_search?from=3&size=3

1.3.2 deep paging(深度分页)

  • deep paging(深度分页):根据相关度评分倒排序,如果分页过深,协调节点会将大量数据聚合分析。
  • deep paging(深度分页)的性能问题:
  • ELK04 - 图1消耗网络带宽:搜索过深的话,各个shard要把数据传递给coordinate node(协调节点),这个过程中有大量的数据传递,消耗网络。
  • ELK04 - 图2消耗内存:各个shard要把数据传递给coordinate node(协调节点),这个传递过来的数据,是被coordinate node(协调节点)保存在内存中的,会大量消耗内存。
  • ELK04 - 图3消耗CPU:coordinate node(协调节点)要把传递过来的数据进行排序,这个排序过程很耗CPU。
  • 总结:鉴于deep paging(深度分页)的性能问题,应该尽量少用之。

1.4 query string基础语法

1.4.1 query string基础语法

  • 语法:根据文档中的某给field包含search content的文档信息
  1. GET /index/_search?q=field:search content
  • 语法:根据文档中的某给field包含search content的文档信息
  1. GET /index/_search?q=+field:search content
  • 语法:根据文档中的某给field不包含search content的文档信息
  1. GET /index/_search?q=-field:search content
  • 示例:查询图书名是java的图书信息
  1. GET /book/_search?q=name:java
  • 示例:查询图书名不是java的图书信息
  1. GET /book/_search?q=-name:java

1.4.2 _all metadata的原理和作用

  • 语法:
  1. GET /index/_search?q=search content
  • 原理:
    • 上述的语法可以搜索所有的field,只要任意一个field包含指定的关键字都可以搜索出来。那么,在进行搜索的时候,难道需要对文档中的每一个field都进行一次搜索吗?答案,显示不是。
    • ES中的all元数据:ES在建立索引的时候,插入一条文档的时候,ES会将所有的field值经过全量分词,把这些分词,放到all field中,在搜索的时候,如果没有指定field,就去_all中搜索。
    • 比如:{name:"tom",age:13}对应_all:tom,13

1.5 query DSL入门

1.5.1 什么是DSL

  1. GET /book/_search?from=0&size=10&q=name:java&sort=price:desc
  • 当query string后面的参数越来越多的时候,搜索条件越来越复杂,不能满足我们的需求,query DSL应运而生。
  • DSL(Domain Specified Language):领域特定语言。
  • ES的DSL,可以在请求体中携带条件,功能非常强大。
  • 语法:查询全部(query string的写法:GET /index/_search
  1. GET /index/_search
  2. {
  3. "query":{
  4. "match_all":{}
  5. }
  6. }
  • 语法:查询某个字段并且按照某个字段排序(query string的写法:GET /index/_search?q=field:search value&sort=field:desc
  1. GET /index/_search
  2. {
  3. "query": {
  4. "match": {
  5. "field": "search value"
  6. }
  7. },
  8. "sort": [
  9. {
  10. "field": {
  11. "order": "desc/asc"
  12. }
  13. }
  14. ]
  15. }
  • 语法:分页查询(query string的写法:GET /index/_search?from=0&size=5
  1. GET /index/_search
  2. {
  3. "query":{
  4. "match_all":{}
  5. },
  6. from: 0,
  7. size: 5
  8. }
  • 语法:返回指定字段(query string的写法:GET /index/_search?_source=field1,field2
  1. GET /index/_search
  2. {
  3. "query": {
  4. "match_all": {}
  5. },
  6. "_source": ["field1","field2"]
  7. }

1.5.2 query DSL语法

  • 语法1:
  1. GET /index/_search
  2. {
  3. QUERY_NAME: {
  4. ARGUMENT: VALUE,
  5. ARGUMENT: VALUE,...
  6. }
  7. }
  • 语法2:
  1. GET /index/_search
  2. {
  3. QUERY_NAME: {
  4. FIELD_NAME: {
  5. ARGUMENT: VALUE,
  6. ARGUMENT: VALUE,...
  7. }
  8. }
  9. }
  • 示例:
  1. GET /test_index/_search
  2. {
  3. "query": {
  4. "match": {
  5. "test_field": "test"
  6. }
  7. }
  8. }

1.5.3 组合多个搜索条件

  • 初始化数据:
  1. PUT /website/_doc/1
  2. {
  3. "title": "my hadoop article",
  4. "content": "hadoop is very bad",
  5. "author_id": 111
  6. }
  1. PUT /website/_doc/2
  2. {
  3. "title": "my elasticsearch article",
  4. "content": "es is very bad",
  5. "author_id": 112
  6. }
  1. PUT /website/_doc/3
  2. {
  3. "title": "my elasticsearch article",
  4. "content": "es is very goods",
  5. "author_id": 111
  6. }
  • 示例:title必须包含elasticsearch,content可以包含elasticsearch也可以不包含elasticsearch,author_id必须不为111。
  1. GET /website/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "must": [
  6. {
  7. "match": {
  8. "title": "elasticsearch"
  9. }
  10. }
  11. ],
  12. "should": [
  13. {
  14. "match": {
  15. "content": "elasticsearch"
  16. }
  17. }
  18. ],
  19. "must_not": [
  20. {
  21. "match": {
  22. "author_id": "111"
  23. }
  24. }
  25. ]
  26. }
  27. }
  28. }

1.6 DSL语法练习

1.6.1 match_all

  • 示例:
  1. GET /book/_search
  2. {
  3. "query": {
  4. "match_all": {}
  5. }
  6. }

1.6.2 match

  • 示例:
  1. GET /book/_search
  2. {
  3. "query": {
  4. "match": {
  5. "description": "java"
  6. }
  7. }
  8. }

1.6.3 multi_match

  • 示例:
  1. GET /book/_search
  2. {
  3. "query": {
  4. "multi_match": {
  5. "query": "java",
  6. "fields": ["name","description"]
  7. }
  8. }
  9. }

1.6.4 range query范围查询

  • 示例:
  1. GET /book/_search
  2. {
  3. "query": {
  4. "range": {
  5. "price": {
  6. "gte": 50,
  7. "lte": 70
  8. }
  9. }
  10. }
  11. }

1.6.5 term query

  • 示例:term query 在查询的时候不分词。
  1. GET /book/_search
  2. {
  3. "query": {
  4. "term": {
  5. "description": {
  6. "value": "java程序员"
  7. }
  8. }
  9. }
  10. }

1.6.6 terms query

  • 示例:
  1. GET /book/_search
  2. {
  3. "query": {
  4. "terms": {
  5. "tags": [
  6. "java",
  7. "dev"
  8. ]
  9. }
  10. }
  11. }

1.6.7 exist query

  • 查询某些文档是否存在某个字段。
  • 示例:
  1. GET /book/_search
  2. {
  3. "query": {
  4. "exists": {"field":"name"}
  5. }
  6. }

1.6.8 fuzzy query

  • 返回包含和搜索词类似的词的文档,该词由Levenshtein编辑距离度量。
  • 包括以下几种情况:
    • ①更改角色(box→fox)。
    • ②删除字符(aple→apple)。
    • ③插入字符(sick→sic)。
    • ④调换两个相邻字符(ACT→CAT)
  • 示例:
  1. GET /book/_search
  2. {
  3. "query": {
  4. "fuzzy": {
  5. "description": {
  6. "value": "java"
  7. }
  8. }
  9. }
  10. }

1.6.9 IDs

  • 示例:
  1. GET /book/_search
  2. {
  3. "query": {
  4. "ids": {
  5. "values": ["1","2","3"]
  6. }
  7. }
  8. }

1.6.10 prefix 前缀查询

  • 示例:
  1. GET /book/_search
  2. {
  3. "query": {
  4. "prefix": {
  5. "description": {
  6. "value": "spring"
  7. }
  8. }
  9. }
  10. }

1.6.11 regexp query正则查询

  • 示例:
  1. GET /book/_search
  2. {
  3. "query": {
  4. "regexp": {
  5. "description": {
  6. "value": "j.*a",
  7. "flags": "ALL",
  8. "max_determinized_states": 10000,
  9. "rewrite": "constant_score"
  10. }
  11. }
  12. }
  13. }

1.7 Filter

1.7.1 query和filter的应用示例

  • 示例:查询“description”中有“java程序员”,并且价格大于50小于90的数据。
  1. GET /book/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "must": [
  6. {
  7. "match": {
  8. "description": "java程序员"
  9. }
  10. },{
  11. "range": {
  12. "price": {
  13. "gte": 50,
  14. "lte": 90
  15. }
  16. }
  17. }
  18. ]
  19. }
  20. }
  21. }
  1. GET /book/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "must": [
  6. {
  7. "match": {
  8. "description": "java程序员"
  9. }
  10. }
  11. ],
  12. "filter": [
  13. {
  14. "range": {
  15. "price": {
  16. "gte": 50,
  17. "lte": 90
  18. }
  19. }
  20. }
  21. ]
  22. }
  23. }
  24. }

1.7.2 query和filter的概念对比

  • query:会去计算每个文档相对于搜索条件的相关度,并按照相关度进行排序。
  • filter:仅仅只是按照搜索条件过滤出需要的数据即可,不计算任何相关度分数,对相关度没有任何影响。
  • 应用场景:
  • ①一般来说,如果我们是在进行搜索,需要将最匹配搜索条件的数据先返回,那么用query。
  • ②如果我们只是根据一些条件筛选出一部分数据,不关注其排序,那么用filter。

1.7.3 query和filter的性能对比

  • query:要计算相关度分数,按照分数进行排序,而且无法cache结果。
  • filter:不需要计算相关度分数,不需要按照相关度分数进行阿皮序,同时还内置的自动cache最常使用filter的数据。比如:keyword,范围查询。

1.8 定位错误语法

  • 验证错误语句:
  1. GET /book/_validate/query?explain
  2. {
  3. "query": {
  4. "mach": {
  5. "name": "java"
  6. }
  7. }
  8. }
  • 返回:
  1. {
  2. "valid" : false,
  3. "error" : "ParsingException[unknown query [mach] did you mean [match]?]; nested: NamedObjectNotFoundException[[3:13] unknown field [mach]];; org.elasticsearch.common.xcontent.NamedObjectNotFoundException: [3:13] unknown field [mach]"
  4. }
  • 正确的语句:
  1. GET /book/_validate/query?explain
  2. {
  3. "query": {
  4. "match": {
  5. "description": "java is good"
  6. }
  7. }
  8. }
  • 返回:
  1. {
  2. "_shards" : {
  3. "total" : 1,
  4. "successful" : 1,
  5. "failed" : 0
  6. },
  7. "valid" : true,
  8. "explanations" : [
  9. {
  10. "index" : "book",
  11. "valid" : true,
  12. "explanation" : "description:java description:is description:good"
  13. }
  14. ]
  15. }
  • 一般在那种特别复杂庞大的搜索下,比如:直接写了数百行的搜索,这个时候我们可以使用validate去验证一下,搜索是否合法。
  • 合法以后,explain就像MySQL中的执行计划,可以看到搜索的目标等信息。

1.9 定制排序规则

1.9.1 默认排序规则

  • 默认情况下,是按照_score进行降序排序的。
  • 但是,某些情况下,可能没有有用的_score,比如说filter。
  • 示例:只过滤
  1. GET /book/_search
  2. {
  3. "query": {
  4. "constant_score": {
  5. "filter": {
  6. "range": {
  7. "price": {
  8. "gte": 50,
  9. "lte": 90
  10. }
  11. }
  12. }
  13. }
  14. }
  15. }

1.9.2 定制排序规则

  • 示例:
  1. GET /book/_search
  2. {
  3. "query": {
  4. "constant_score": {
  5. "filter": {
  6. "term": {
  7. "studymodel": "201001"
  8. }
  9. }
  10. }
  11. },
  12. "sort": [
  13. {
  14. "price": {
  15. "order": "desc"
  16. }
  17. }
  18. ]
  19. }

1.10 Text字段排序问题

  • 场景:数据库中按照某个字段排序,SQL只需要写order by 字段名即可。
  • 如果在ES对一个text的field进行排序,ES是无法进行排序的。因为文档存储到索引表的时候,是分词存储的,ES无法知道此字段的真实值。
  • 通常的解决方案:
  • 方案一:设置fielddata:true。此种方式有弊端,比如下面的title是不计入相关度查询的,而且是按照第一个分词排序的。
  1. PUT /website
  2. {
  3. "mappings": {
  4. "properties": {
  5. "title": {
  6. "type": "text",
  7. "fielddata": true
  8. },
  9. "content": {
  10. "type": "text"
  11. },
  12. "post_date": {
  13. "type": "date"
  14. },
  15. "author_id": {
  16. "type": "long"
  17. }
  18. }
  19. }
  20. }
  • 方案二:将一个text类型的field字段建立两次索引,一个分词,用来进行搜索;一个分词,用来进行排序。
  1. PUT /website
  2. {
  3. "mappings": {
  4. "properties": {
  5. "title": {
  6. "type": "text",
  7. "fields": {
  8. "keyword":{
  9. "type":"keyword"
  10. }
  11. }
  12. },
  13. "content": {
  14. "type": "text"
  15. },
  16. "post_date": {
  17. "type": "date"
  18. },
  19. "author_id": {
  20. "type": "long"
  21. }
  22. }
  23. }
  24. }
  1. PUT /website/_doc/1
  2. {
  3. "title": "first article",
  4. "content": "this is my second article",
  5. "post_date": "2019-01-01",
  6. "author_id": 110
  7. }
  1. PUT /website/_doc/2
  2. {
  3. "title": "second article",
  4. "content": "this is my second article",
  5. "post_date": "2019-01-01",
  6. "author_id": 110
  7. }
  1. PUT /website/_doc/3
  2. {
  3. "title": "third article",
  4. "content": "this is my third article",
  5. "post_date": "2019-01-02",
  6. "author_id": 110
  7. }
  1. GET /website/_search
  2. {
  3. "query": {
  4. "match_all": {}
  5. },
  6. "sort": [
  7. {
  8. "title.keyword": {
  9. "order": "desc"
  10. }
  11. }
  12. ]
  13. }

1.11 scroll分批查询

  • 场景:下载某一个索引中的一亿条数据到文件或数据库中,不能一下全查出来,容易造成系统内存溢出,可以采用scroll滚动搜索技术,一批一批的查询。
  • scroll搜索会在第一次搜索的时候,保存一个当时的视图快照,之后只会基于该视图快照提供数据搜索,如果这个期间数据发生变更,是不会让用户看到的。
  • 每次发送scroll请求,需要指定一个scroll参数,指定一个时间窗口,每次搜索请求只要在这个时间窗口内能完成就可以了。
  • scroll分批查询的步骤:
  • ELK04 - 图4搜索:下面的语句表示1分钟查询2条数据
  1. GET /book/_search?scroll=1m
  2. {
  3. "query": {
  4. "match_all": {}
  5. },
  6. "size": 2
  7. }
  • 返回:获取的结果中包含_scroll_id字段。
  1. {
  2. "_scroll_id" : "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFktoNzhPVE1qUUhTaUctdTFmUEpaRkEAAAAAAAAcgxZNVFl2VXhVV1JTcVNFMkdMc1g4X3pn",
  3. "took" : 0,
  4. "timed_out" : false,
  5. "_shards" : {
  6. "total" : 1,
  7. "successful" : 1,
  8. "skipped" : 0,
  9. "failed" : 0
  10. },
  11. "hits" : {
  12. "total" : {
  13. "value" : 10,
  14. "relation" : "eq"
  15. },
  16. "max_score" : 1.0,
  17. "hits" : [
  18. {
  19. "_index" : "book",
  20. "_type" : "_doc",
  21. "_id" : "1",
  22. "_score" : 1.0,
  23. "_source" : {
  24. "name" : "Bootstrap开发",
  25. "description" : "Bootstrap是由Twitter推出的一个前台页面开发css框架,是一个非常流行的开发框架,此框架集成了多种页面效果。此开发框架包含了大量的CSS、JS程序代码,可以帮助开发者(尤其是不擅长css页面开发的程序人员)轻松的实现一个css,不受浏览器限制的精美界面css效果。",
  26. "studymodel" : "201002",
  27. "price" : 38.6,
  28. "timestamp" : "2019-08-25 19:11:35",
  29. "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
  30. "tags" : [
  31. "bootstrap",
  32. "dev"
  33. ]
  34. }
  35. },
  36. {
  37. "_index" : "book",
  38. "_type" : "_doc",
  39. "_id" : "2",
  40. "_score" : 1.0,
  41. "_source" : {
  42. "name" : "java编程思想",
  43. "description" : "java语言是世界第一编程语言,在软件开发领域使用人数最多。",
  44. "studymodel" : "201001",
  45. "price" : 68.6,
  46. "timestamp" : "2019-08-25 19:11:35",
  47. "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
  48. "tags" : [
  49. "java",
  50. "dev"
  51. ]
  52. }
  53. }
  54. ]
  55. }
  56. }
  • ELK04 - 图5拿第一步获取的scroll_id字段的值,再发送一次scroll请求:
  1. GET /_search/scroll
  2. {
  3. "scroll":"1m",
  4. "scroll_id": "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFktoNzhPVE1qUUhTaUctdTFmUEpaRkEAAAAAAAAc2xZNVFl2VXhVV1JTcVNFMkdMc1g4X3pn"
  5. }
  • ELK04 - 图6重复第二步,直到查不到数据为止。

scroll分批查询和分页查询的区别:

  • 分页查询是给用户看得。
  • scroll分批查询是系统内部操作,比如批量下载数据,转移数据、零停机改变索引映射(这种方式太麻烦,弃用,ES有更好的方式实现)等等。

2 Java API实现搜索

2.1 match_all

  • 示例:
  1. package com.sunxaiping.elk;
  2. import org.elasticsearch.action.search.SearchRequest;
  3. import org.elasticsearch.action.search.SearchResponse;
  4. import org.elasticsearch.client.RequestOptions;
  5. import org.elasticsearch.client.RestHighLevelClient;
  6. import org.elasticsearch.index.query.QueryBuilders;
  7. import org.elasticsearch.search.SearchHit;
  8. import org.elasticsearch.search.SearchHits;
  9. import org.elasticsearch.search.builder.SearchSourceBuilder;
  10. import org.junit.jupiter.api.Test;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.boot.test.context.SpringBootTest;
  13. import java.io.IOException;
  14. import java.util.Map;
  15. /**
  16. * Query DSL
  17. */
  18. @SpringBootTest
  19. public class ElkApplicationTests {
  20. @Autowired
  21. private RestHighLevelClient client;
  22. /**
  23. * 搜索全部记录
  24. *
  25. <pre>
  26. * GET /book/_search
  27. * {
  28. * "query": {
  29. * "match_all": {}
  30. * }
  31. * }
  32. * </pre>
  33. */
  34. @Test
  35. public void testMatchAll() throws IOException {
  36. //创建请求
  37. SearchRequest searchRequest = new SearchRequest("book");
  38. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  39. searchSourceBuilder.query(QueryBuilders.matchAllQuery());
  40. //返回某些字段
  41. searchSourceBuilder.fetchSource(List.of("price", "name", "description").toArray(String[]::new), List.of().toArray(String[]::new));
  42. searchRequest.source(searchSourceBuilder);
  43. //发送请求
  44. SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
  45. //返回结果
  46. SearchHits hits = response.getHits();
  47. SearchHit[] searchHits = hits.getHits();
  48. for (SearchHit searchHit : searchHits) {
  49. String index = searchHit.getIndex();
  50. System.out.println("index = " + index);
  51. String type = searchHit.getType();
  52. System.out.println("type = " + type);
  53. String id = searchHit.getId();
  54. System.out.println("id = " + id);
  55. float score = searchHit.getScore();
  56. System.out.println("score = " + score);
  57. Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
  58. System.out.println("sourceAsMap = " + sourceAsMap);
  59. }
  60. }
  61. }

2.2 match

  • 示例:
  1. package com.sunxaiping.elk;
  2. import org.elasticsearch.action.search.SearchRequest;
  3. import org.elasticsearch.action.search.SearchResponse;
  4. import org.elasticsearch.client.RequestOptions;
  5. import org.elasticsearch.client.RestHighLevelClient;
  6. import org.elasticsearch.index.query.QueryBuilders;
  7. import org.elasticsearch.search.SearchHit;
  8. import org.elasticsearch.search.SearchHits;
  9. import org.elasticsearch.search.builder.SearchSourceBuilder;
  10. import org.junit.jupiter.api.Test;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.boot.test.context.SpringBootTest;
  13. import java.io.IOException;
  14. import java.util.List;
  15. import java.util.Map;
  16. /**
  17. * Query DSL
  18. */
  19. @SpringBootTest
  20. public class ElkApplicationTests {
  21. @Autowired
  22. private RestHighLevelClient client;
  23. /**
  24. *
  25. <pre>
  26. * GET /book/_search
  27. * {
  28. * "query": {
  29. * "match": {
  30. * "name": "java"
  31. * }
  32. * }
  33. * }
  34. * </pre>
  35. */
  36. @Test
  37. public void testMatchAll() throws IOException {
  38. //创建请求
  39. SearchRequest searchRequest = new SearchRequest("book");
  40. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  41. searchSourceBuilder.query(QueryBuilders.matchQuery("name", "java"));
  42. //返回某些字段
  43. searchSourceBuilder.fetchSource(List.of("price", "name", "description").toArray(String[]::new), List.of().toArray(String[]::new));
  44. searchRequest.source(searchSourceBuilder);
  45. //发送请求
  46. SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
  47. //返回结果
  48. SearchHits hits = response.getHits();
  49. SearchHit[] searchHits = hits.getHits();
  50. for (SearchHit searchHit : searchHits) {
  51. String index = searchHit.getIndex();
  52. System.out.println("index = " + index);
  53. String type = searchHit.getType();
  54. System.out.println("type = " + type);
  55. String id = searchHit.getId();
  56. System.out.println("id = " + id);
  57. float score = searchHit.getScore();
  58. System.out.println("score = " + score);
  59. Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
  60. System.out.println("sourceAsMap = " + sourceAsMap);
  61. }
  62. }
  63. }

2.3 multi_match

  • 示例:
  1. package com.sunxaiping.elk;
  2. import org.elasticsearch.action.search.SearchRequest;
  3. import org.elasticsearch.action.search.SearchResponse;
  4. import org.elasticsearch.client.RequestOptions;
  5. import org.elasticsearch.client.RestHighLevelClient;
  6. import org.elasticsearch.index.query.QueryBuilders;
  7. import org.elasticsearch.search.SearchHit;
  8. import org.elasticsearch.search.SearchHits;
  9. import org.elasticsearch.search.builder.SearchSourceBuilder;
  10. import org.junit.jupiter.api.Test;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.boot.test.context.SpringBootTest;
  13. import java.io.IOException;
  14. import java.util.List;
  15. import java.util.Map;
  16. /**
  17. * Query DSL
  18. */
  19. @SpringBootTest
  20. public class ElkApplicationTests {
  21. @Autowired
  22. private RestHighLevelClient client;
  23. /**
  24. *
  25. <pre>
  26. * GET /book/_search
  27. * {
  28. * "query": {
  29. * "multi_match": {
  30. * "query": "java",
  31. * "fields": ["name","description"]
  32. * }
  33. * }
  34. * }
  35. * </pre>
  36. */
  37. @Test
  38. public void testMatchAll() throws IOException {
  39. //创建请求
  40. SearchRequest searchRequest = new SearchRequest("book");
  41. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  42. searchSourceBuilder.query(QueryBuilders.multiMatchQuery("java", "name","description"));
  43. //返回某些字段
  44. searchSourceBuilder.fetchSource(List.of("price", "name", "description").toArray(String[]::new), List.of().toArray(String[]::new));
  45. searchRequest.source(searchSourceBuilder);
  46. //发送请求
  47. SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
  48. //返回结果
  49. SearchHits hits = response.getHits();
  50. SearchHit[] searchHits = hits.getHits();
  51. for (SearchHit searchHit : searchHits) {
  52. String index = searchHit.getIndex();
  53. System.out.println("index = " + index);
  54. String type = searchHit.getType();
  55. System.out.println("type = " + type);
  56. String id = searchHit.getId();
  57. System.out.println("id = " + id);
  58. float score = searchHit.getScore();
  59. System.out.println("score = " + score);
  60. Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
  61. System.out.println("sourceAsMap = " + sourceAsMap);
  62. }
  63. }
  64. }

2.4 分页搜索

  • 示例:
  1. package com.sunxaiping.elk;
  2. import org.elasticsearch.action.search.SearchRequest;
  3. import org.elasticsearch.action.search.SearchResponse;
  4. import org.elasticsearch.client.RequestOptions;
  5. import org.elasticsearch.client.RestHighLevelClient;
  6. import org.elasticsearch.index.query.QueryBuilders;
  7. import org.elasticsearch.search.SearchHit;
  8. import org.elasticsearch.search.SearchHits;
  9. import org.elasticsearch.search.builder.SearchSourceBuilder;
  10. import org.junit.jupiter.api.Test;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.boot.test.context.SpringBootTest;
  13. import java.io.IOException;
  14. import java.util.List;
  15. import java.util.Map;
  16. /**
  17. * Query DSL
  18. */
  19. @SpringBootTest
  20. public class ElkApplicationTests {
  21. @Autowired
  22. private RestHighLevelClient client;
  23. /**
  24. *
  25. <pre>
  26. * GET /book/_search
  27. * {
  28. * "query": {
  29. * "match_all": {}
  30. * },
  31. * "from": 0,
  32. * "size": 5
  33. * }
  34. * </pre>
  35. */
  36. @Test
  37. public void testPagingQuery() throws IOException {
  38. Integer pageNo = 1;
  39. Integer pageSize = 5;
  40. //创建请求
  41. SearchRequest searchRequest = new SearchRequest("book");
  42. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  43. searchSourceBuilder.query(QueryBuilders.matchAllQuery());
  44. searchSourceBuilder.from((pageNo - 1) * pageSize);
  45. searchSourceBuilder.size(pageSize);
  46. //返回某些字段
  47. searchSourceBuilder.fetchSource(List.of("price", "name", "description").toArray(String[]::new), List.of().toArray(String[]::new));
  48. searchRequest.source(searchSourceBuilder);
  49. //发送请求
  50. SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
  51. //返回结果
  52. SearchHits hits = response.getHits();
  53. SearchHit[] searchHits = hits.getHits();
  54. for (SearchHit searchHit : searchHits) {
  55. String index = searchHit.getIndex();
  56. System.out.println("index = " + index);
  57. String type = searchHit.getType();
  58. System.out.println("type = " + type);
  59. String id = searchHit.getId();
  60. System.out.println("id = " + id);
  61. float score = searchHit.getScore();
  62. System.out.println("score = " + score);
  63. Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
  64. System.out.println("sourceAsMap = " + sourceAsMap);
  65. }
  66. }
  67. }

2.5 IDs

  • 示例:
  1. package com.sunxaiping.elk;
  2. import org.elasticsearch.action.search.SearchRequest;
  3. import org.elasticsearch.action.search.SearchResponse;
  4. import org.elasticsearch.client.RequestOptions;
  5. import org.elasticsearch.client.RestHighLevelClient;
  6. import org.elasticsearch.index.query.QueryBuilders;
  7. import org.elasticsearch.search.SearchHit;
  8. import org.elasticsearch.search.SearchHits;
  9. import org.elasticsearch.search.builder.SearchSourceBuilder;
  10. import org.junit.jupiter.api.Test;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.boot.test.context.SpringBootTest;
  13. import java.io.IOException;
  14. import java.util.List;
  15. import java.util.Map;
  16. /**
  17. * Query DSL
  18. */
  19. @SpringBootTest
  20. public class ElkApplicationTests {
  21. @Autowired
  22. private RestHighLevelClient client;
  23. /**
  24. *
  25. <pre>
  26. * GET /book/_search
  27. * {
  28. * "query": {
  29. * "ids": {
  30. * "values": ["1","2","3"]
  31. * }
  32. * }
  33. * }
  34. * </pre>
  35. */
  36. @Test
  37. public void testIDs() throws IOException {
  38. //创建请求
  39. SearchRequest searchRequest = new SearchRequest("book");
  40. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  41. searchSourceBuilder.query(QueryBuilders.idsQuery().addIds("1", "2", "3"));
  42. //返回某些字段
  43. searchSourceBuilder.fetchSource(List.of("price", "name", "description").toArray(String[]::new), List.of().toArray(String[]::new));
  44. searchRequest.source(searchSourceBuilder);
  45. //发送请求
  46. SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
  47. //返回结果
  48. SearchHits hits = response.getHits();
  49. SearchHit[] searchHits = hits.getHits();
  50. for (SearchHit searchHit : searchHits) {
  51. String index = searchHit.getIndex();
  52. System.out.println("index = " + index);
  53. String type = searchHit.getType();
  54. System.out.println("type = " + type);
  55. String id = searchHit.getId();
  56. System.out.println("id = " + id);
  57. float score = searchHit.getScore();
  58. System.out.println("score = " + score);
  59. Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
  60. System.out.println("sourceAsMap = " + sourceAsMap);
  61. }
  62. }
  63. }

2.6 term query

  • 示例:
  1. package com.sunxaiping.elk;
  2. import org.elasticsearch.action.search.SearchRequest;
  3. import org.elasticsearch.action.search.SearchResponse;
  4. import org.elasticsearch.client.RequestOptions;
  5. import org.elasticsearch.client.RestHighLevelClient;
  6. import org.elasticsearch.index.query.QueryBuilders;
  7. import org.elasticsearch.search.SearchHit;
  8. import org.elasticsearch.search.SearchHits;
  9. import org.elasticsearch.search.builder.SearchSourceBuilder;
  10. import org.junit.jupiter.api.Test;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.boot.test.context.SpringBootTest;
  13. import java.io.IOException;
  14. import java.util.List;
  15. import java.util.Map;
  16. /**
  17. * Query DSL
  18. */
  19. @SpringBootTest
  20. public class ElkApplicationTests {
  21. @Autowired
  22. private RestHighLevelClient client;
  23. /**
  24. *
  25. <pre>
  26. * GET /book/_search
  27. * {
  28. * "query": {
  29. * "term": {
  30. * "description": {
  31. * "value": "java"
  32. * }
  33. * }
  34. * }
  35. * }
  36. * </pre>
  37. */
  38. @Test
  39. public void testTermQuery() throws IOException {
  40. //创建请求
  41. SearchRequest searchRequest = new SearchRequest("book");
  42. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  43. searchSourceBuilder.query(QueryBuilders.termQuery("description", "java"));
  44. //返回某些字段
  45. searchSourceBuilder.fetchSource(List.of("price", "name", "description").toArray(String[]::new), List.of().toArray(String[]::new));
  46. searchRequest.source(searchSourceBuilder);
  47. //发送请求
  48. SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
  49. //返回结果
  50. SearchHits hits = response.getHits();
  51. SearchHit[] searchHits = hits.getHits();
  52. for (SearchHit searchHit : searchHits) {
  53. String index = searchHit.getIndex();
  54. System.out.println("index = " + index);
  55. String type = searchHit.getType();
  56. System.out.println("type = " + type);
  57. String id = searchHit.getId();
  58. System.out.println("id = " + id);
  59. float score = searchHit.getScore();
  60. System.out.println("score = " + score);
  61. Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
  62. System.out.println("sourceAsMap = " + sourceAsMap);
  63. }
  64. }
  65. }

2.7 range query

  • 示例:
  1. package com.sunxaiping.elk;
  2. import org.elasticsearch.action.search.SearchRequest;
  3. import org.elasticsearch.action.search.SearchResponse;
  4. import org.elasticsearch.client.RequestOptions;
  5. import org.elasticsearch.client.RestHighLevelClient;
  6. import org.elasticsearch.index.query.QueryBuilders;
  7. import org.elasticsearch.search.SearchHit;
  8. import org.elasticsearch.search.SearchHits;
  9. import org.elasticsearch.search.builder.SearchSourceBuilder;
  10. import org.junit.jupiter.api.Test;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.boot.test.context.SpringBootTest;
  13. import java.io.IOException;
  14. import java.util.List;
  15. import java.util.Map;
  16. /**
  17. * Query DSL
  18. */
  19. @SpringBootTest
  20. public class ElkApplicationTests {
  21. @Autowired
  22. private RestHighLevelClient client;
  23. /**
  24. *
  25. <pre>
  26. * GET /book/_search
  27. * {
  28. * "query": {
  29. * "range": {
  30. * "price": {
  31. * "gte": 50,
  32. * "lte": 70
  33. * }
  34. * }
  35. * }
  36. * }
  37. * </pre>
  38. */
  39. @Test
  40. public void testRangeQuery() throws IOException {
  41. //创建请求
  42. SearchRequest searchRequest = new SearchRequest("book");
  43. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  44. searchSourceBuilder.query(QueryBuilders.rangeQuery("price").gte(50).lte(70));
  45. //返回某些字段
  46. searchSourceBuilder.fetchSource(List.of("price", "name", "description").toArray(String[]::new), List.of().toArray(String[]::new));
  47. searchRequest.source(searchSourceBuilder);
  48. //发送请求
  49. SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
  50. //返回结果
  51. SearchHits hits = response.getHits();
  52. SearchHit[] searchHits = hits.getHits();
  53. for (SearchHit searchHit : searchHits) {
  54. String index = searchHit.getIndex();
  55. System.out.println("index = " + index);
  56. String type = searchHit.getType();
  57. System.out.println("type = " + type);
  58. String id = searchHit.getId();
  59. System.out.println("id = " + id);
  60. float score = searchHit.getScore();
  61. System.out.println("score = " + score);
  62. Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
  63. System.out.println("sourceAsMap = " + sourceAsMap);
  64. }
  65. }
  66. }

2.8 bool query

  • 示例:
  1. package com.sunxaiping.elk;
  2. import org.elasticsearch.action.search.SearchRequest;
  3. import org.elasticsearch.action.search.SearchResponse;
  4. import org.elasticsearch.client.RequestOptions;
  5. import org.elasticsearch.client.RestHighLevelClient;
  6. import org.elasticsearch.index.query.BoolQueryBuilder;
  7. import org.elasticsearch.index.query.QueryBuilders;
  8. import org.elasticsearch.search.SearchHit;
  9. import org.elasticsearch.search.SearchHits;
  10. import org.elasticsearch.search.builder.SearchSourceBuilder;
  11. import org.junit.jupiter.api.Test;
  12. import org.springframework.beans.factory.annotation.Autowired;
  13. import org.springframework.boot.test.context.SpringBootTest;
  14. import java.io.IOException;
  15. import java.util.List;
  16. import java.util.Map;
  17. /**
  18. * Query DSL
  19. */
  20. @SpringBootTest
  21. public class ElkApplicationTests {
  22. @Autowired
  23. private RestHighLevelClient client;
  24. /**
  25. *
  26. <pre>
  27. * GET /book/_search
  28. * {
  29. * "query": {
  30. * "bool": {
  31. * "must": [
  32. * {
  33. * "multi_match": {
  34. * "query": "java程序员",
  35. * "fields": ["name","description"]
  36. * }
  37. * }
  38. * ],
  39. * "should": [
  40. * {
  41. * "match": {
  42. * "studymodel": "201001"
  43. * }
  44. * }
  45. * ]
  46. * }
  47. * }
  48. * }
  49. * </pre>
  50. */
  51. @Test
  52. public void testBoolQuery() throws IOException {
  53. //创建请求
  54. SearchRequest searchRequest = new SearchRequest("book");
  55. BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
  56. boolQueryBuilder.must(QueryBuilders.multiMatchQuery("java程序员", "name","description"));
  57. boolQueryBuilder.should(QueryBuilders.matchQuery("studymodel", "201001"));
  58. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  59. searchSourceBuilder.query(boolQueryBuilder);
  60. //返回某些字段
  61. searchSourceBuilder.fetchSource(List.of("price", "name", "description").toArray(String[]::new), List.of().toArray(String[]::new));
  62. searchRequest.source(searchSourceBuilder);
  63. //发送请求
  64. SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
  65. //返回结果
  66. SearchHits hits = response.getHits();
  67. SearchHit[] searchHits = hits.getHits();
  68. for (SearchHit searchHit : searchHits) {
  69. String index = searchHit.getIndex();
  70. System.out.println("index = " + index);
  71. String type = searchHit.getType();
  72. System.out.println("type = " + type);
  73. String id = searchHit.getId();
  74. System.out.println("id = " + id);
  75. float score = searchHit.getScore();
  76. System.out.println("score = " + score);
  77. Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
  78. System.out.println("sourceAsMap = " + sourceAsMap);
  79. }
  80. }
  81. }

2.9 Filter

  • 示例:
  1. package com.sunxaiping.elk;
  2. import org.elasticsearch.action.search.SearchRequest;
  3. import org.elasticsearch.action.search.SearchResponse;
  4. import org.elasticsearch.client.RequestOptions;
  5. import org.elasticsearch.client.RestHighLevelClient;
  6. import org.elasticsearch.index.query.QueryBuilders;
  7. import org.elasticsearch.search.SearchHit;
  8. import org.elasticsearch.search.SearchHits;
  9. import org.elasticsearch.search.builder.SearchSourceBuilder;
  10. import org.junit.jupiter.api.Test;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.boot.test.context.SpringBootTest;
  13. import java.io.IOException;
  14. import java.util.List;
  15. import java.util.Map;
  16. /**
  17. * Query DSL
  18. */
  19. @SpringBootTest
  20. public class ElkApplicationTests {
  21. @Autowired
  22. private RestHighLevelClient client;
  23. /**
  24. *
  25. <pre>
  26. * GET /book/_search
  27. * {
  28. * "query": {
  29. * "constant_score": {
  30. * "filter": {
  31. * "range": {
  32. * "price": {
  33. * "gte": 50,
  34. * "lte": 90
  35. * }
  36. * }
  37. * }
  38. * }
  39. * }
  40. * }
  41. * </pre>
  42. */
  43. @Test
  44. public void testFilter() throws IOException {
  45. //创建请求
  46. SearchRequest searchRequest = new SearchRequest("book");
  47. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  48. searchSourceBuilder.query(QueryBuilders.constantScoreQuery(QueryBuilders.rangeQuery("price").gte(50).lte(70)));
  49. //返回某些字段
  50. searchSourceBuilder.fetchSource(List.of("price", "name", "description").toArray(String[]::new), List.of().toArray(String[]::new));
  51. searchRequest.source(searchSourceBuilder);
  52. //发送请求
  53. SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
  54. //返回结果
  55. SearchHits hits = response.getHits();
  56. SearchHit[] searchHits = hits.getHits();
  57. for (SearchHit searchHit : searchHits) {
  58. String index = searchHit.getIndex();
  59. System.out.println("index = " + index);
  60. String type = searchHit.getType();
  61. System.out.println("type = " + type);
  62. String id = searchHit.getId();
  63. System.out.println("id = " + id);
  64. float score = searchHit.getScore();
  65. System.out.println("score = " + score);
  66. Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
  67. System.out.println("sourceAsMap = " + sourceAsMap);
  68. }
  69. }
  70. }
  • 示例:
  1. package com.sunxaiping.elk;
  2. import org.elasticsearch.action.search.SearchRequest;
  3. import org.elasticsearch.action.search.SearchResponse;
  4. import org.elasticsearch.client.RequestOptions;
  5. import org.elasticsearch.client.RestHighLevelClient;
  6. import org.elasticsearch.index.query.BoolQueryBuilder;
  7. import org.elasticsearch.index.query.QueryBuilders;
  8. import org.elasticsearch.search.SearchHit;
  9. import org.elasticsearch.search.SearchHits;
  10. import org.elasticsearch.search.builder.SearchSourceBuilder;
  11. import org.junit.jupiter.api.Test;
  12. import org.springframework.beans.factory.annotation.Autowired;
  13. import org.springframework.boot.test.context.SpringBootTest;
  14. import java.io.IOException;
  15. import java.util.List;
  16. import java.util.Map;
  17. /**
  18. * Query DSL
  19. */
  20. @SpringBootTest
  21. public class ElkApplicationTests {
  22. @Autowired
  23. private RestHighLevelClient client;
  24. /**
  25. *
  26. <pre>
  27. * GET /book/_search
  28. * {
  29. * "query": {
  30. * "bool": {
  31. * "must": [
  32. * {
  33. * "multi_match": {
  34. * "query": "java程序员",
  35. * "fields": ["name","description"]
  36. * }
  37. * }
  38. * ],
  39. * "should": [
  40. * {
  41. * "match": {
  42. * "studymodel": "201001"
  43. * }
  44. * }
  45. * ],
  46. * "filter": [
  47. * {
  48. * "range": {
  49. * "price": {
  50. * "gte": 50,
  51. * "lte": 90
  52. * }
  53. * }
  54. * }
  55. * ]
  56. * }
  57. * }
  58. * }
  59. * </pre>
  60. */
  61. @Test
  62. public void testFilter() throws IOException {
  63. //创建请求
  64. SearchRequest searchRequest = new SearchRequest("book");
  65. BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
  66. boolQueryBuilder.must(QueryBuilders.multiMatchQuery("java程序员", "name","description"));
  67. boolQueryBuilder.should(QueryBuilders.matchQuery("studymodel", "201001"));
  68. boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(50).lte(90));
  69. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  70. searchSourceBuilder.query(boolQueryBuilder);
  71. //返回某些字段
  72. searchSourceBuilder.fetchSource(List.of("price", "name", "description").toArray(String[]::new), List.of().toArray(String[]::new));
  73. searchRequest.source(searchSourceBuilder);
  74. //发送请求
  75. SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
  76. //返回结果
  77. SearchHits hits = response.getHits();
  78. SearchHit[] searchHits = hits.getHits();
  79. for (SearchHit searchHit : searchHits) {
  80. String index = searchHit.getIndex();
  81. System.out.println("index = " + index);
  82. String type = searchHit.getType();
  83. System.out.println("type = " + type);
  84. String id = searchHit.getId();
  85. System.out.println("id = " + id);
  86. float score = searchHit.getScore();
  87. System.out.println("score = " + score);
  88. Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
  89. System.out.println("sourceAsMap = " + sourceAsMap);
  90. }
  91. }
  92. }

2.10 排序

  • 示例:
  1. package com.sunxaiping.elk;
  2. import org.elasticsearch.action.search.SearchRequest;
  3. import org.elasticsearch.action.search.SearchResponse;
  4. import org.elasticsearch.client.RequestOptions;
  5. import org.elasticsearch.client.RestHighLevelClient;
  6. import org.elasticsearch.index.query.QueryBuilders;
  7. import org.elasticsearch.search.SearchHit;
  8. import org.elasticsearch.search.SearchHits;
  9. import org.elasticsearch.search.builder.SearchSourceBuilder;
  10. import org.elasticsearch.search.sort.SortOrder;
  11. import org.junit.jupiter.api.Test;
  12. import org.springframework.beans.factory.annotation.Autowired;
  13. import org.springframework.boot.test.context.SpringBootTest;
  14. import java.io.IOException;
  15. import java.util.List;
  16. import java.util.Map;
  17. /**
  18. * Query DSL
  19. */
  20. @SpringBootTest
  21. public class ElkApplicationTests {
  22. @Autowired
  23. private RestHighLevelClient client;
  24. /**
  25. *
  26. <pre>
  27. * GET /book/_search
  28. * {
  29. * "query": {
  30. * "multi_match": {
  31. * "query": "java程序员",
  32. * "fields": [
  33. * "name",
  34. * "description"
  35. * ]
  36. * }
  37. * },
  38. * "sort": [
  39. * {
  40. * "price": {
  41. * "order": "desc"
  42. * }
  43. * }
  44. * ]
  45. * }
  46. * </pre>
  47. */
  48. @Test
  49. public void testSort() throws IOException {
  50. //创建请求
  51. SearchRequest searchRequest = new SearchRequest("book");
  52. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  53. searchSourceBuilder.query(QueryBuilders.multiMatchQuery("java程序员", "name", "description"));
  54. searchSourceBuilder.sort("price", SortOrder.DESC);
  55. //返回某些字段
  56. searchSourceBuilder.fetchSource(List.of("price", "name", "description").toArray(String[]::new), List.of().toArray(String[]::new));
  57. searchRequest.source(searchSourceBuilder);
  58. //发送请求
  59. SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
  60. //返回结果
  61. SearchHits hits = response.getHits();
  62. SearchHit[] searchHits = hits.getHits();
  63. for (SearchHit searchHit : searchHits) {
  64. String index = searchHit.getIndex();
  65. System.out.println("index = " + index);
  66. String type = searchHit.getType();
  67. System.out.println("type = " + type);
  68. String id = searchHit.getId();
  69. System.out.println("id = " + id);
  70. Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
  71. System.out.println("sourceAsMap = " + sourceAsMap);
  72. }
  73. }
  74. }