• ElasticSearch7.3学习(二十二)----Text字段排序、Scroll分批查询场景解析


    1、Text字段排序

    场景:数据库中按照某个字段排序,sql只需写order by 字段名即可,如果es对一个text field进行排序,es中无法排序。因为文档入倒排索引表时,分词存入,es无法知道此字段的真实值。这样的结果往往不准确,因为分词后是多个单词,再排序就不是我们想要的结果了。

    通常有两种解决办法:

    1. 将一个text field建立两次索引,一个分词,用来进行搜索;一个不分词,用来进行排序。
    2. mapping时设置fielddata:true,按照第一个分词进行字典序排序。这种方式也不是很准确,因为只是按照第一个分词进行排序,后续的分词不会参与排序。fielddata:true的排序是对text内部分词结果进行排序之后再进行外部排序的,效率低不推荐使用;

    样例如下:

    首先建立索引

    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. "fielddata": true
    16. },
    17. "post_date": {
    18. "type": "date"
    19. },
    20. "author_id": {
    21. "type": "long"
    22. }
    23. }
    24. }
    25. }

    插入数据

    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. }
    8. PUT /website/_doc/2
    9. {
    10. "title": "second article",
    11. "content": "this is my second article",
    12. "post_date": "2019-01-01",
    13. "author_id": 110
    14. }
    15. PUT /website/_doc/3
    16. {
    17. "title": "third article",
    18. "content": "this is my third article",
    19. "post_date": "2019-01-02",
    20. "author_id": 110
    21. }

    搜索,按照整个title的值进行排序

    1. GET /website/_search
    2. {
    3. "query": {
    4.   "match_all": {}
    5. },
    6. "sort": [
    7.   {
    8.     "title.keyword": {
    9.       "order": "desc"
    10.     }
    11.   }
    12. ]
    13. }

    结果如下:

    可以看出是以title的内容进行排序

    然后再看下"fielddata": true这种情况,对content进行排序

    1. GET /website/_search
    2. {
    3. "query": {
    4. "match_all": {}
    5. },
    6. "sort": [
    7. {
    8. "content": {
    9. "order": "desc"
    10. }
    11. }
    12. ]
    13. }

    结果如下:

    结果是以分词后的第一个单词进行排序,排序结果不准确,所以不推荐使用。

    2、Scroll分批查询

    场景:下载某一个索引中1亿条数据,到文件或是数据库。

    不能一下全查出来,这样会造成系统内存溢出。所以使用scoll滚动搜索技术,一批一批查询。scoll搜索会在第一次搜索的时候,保存一个当时的视图快照,之后只会基于该旧的视图快照提供数据搜索,如果这个期间数据变更,是不会让用户看到的。每次发送scroll请求,我们还需要指定一个scoll参数,指定一个时间窗口,每次搜索请求只要在这个时间窗口内能完成就可以了。

    假如有三亿条数据,这里实际只有3条

    添加测试数据

    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": [
    10.   "bootstrap",
    11.   "dev"
    12. ]
    13. }
    14. PUT /book/_doc/2
    15. {
    16. "name": "java编程思想",
    17. "description": "java语言是世界第一编程语言,在软件开发领域使用人数最多。",
    18. "studymodel": "201001",
    19. "price": 68.6,
    20. "timestamp": "2019-08-25 19:11:35",
    21. "pic": "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
    22. "tags": [
    23.   "java",
    24.   "dev"
    25. ]
    26. }
    27. PUT /book/_doc/3
    28. {
    29. "name": "spring开发基础",
    30. "description": "spring 在java领域非常流行,java程序员都在用。",
    31. "studymodel": "201001",
    32. "price": 88.6,
    33. "timestamp": "2019-08-24 19:11:35",
    34. "pic": "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
    35. "tags": [
    36.   "spring",
    37.   "java"
    38. ]
    39. }

    搜索

    1. GET /book/_search?scroll=1m
    2. {
    3. "query": {
    4. "match_all": {}
    5. },
    6. "size": 1
    7. }

    首先获取第一批次的数据,这里只返回一条。

    1. {
    2. "_scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAByQWQWx5bzRmTW9TeUNpNmVvN0E2dF9YQQ==",
    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" : 3,
    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是一个非常流行的开发框架。此开发框架可以帮助不擅长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. }
    38. }

    可以看到获取到了第一条的数据,获得的结果里面包含有一个scoll_id,下一次再发送scoll请求的时候,必须带上这个scoll_id,接下来获取第二条数据

    1. GET /_search/scroll
    2. {
    3. "scroll": "1m",
    4. "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAByQWQWx5bzRmTW9TeUNpNmVvN0E2dF9YQQ=="
    5. }

    获取成功第二条数据

    1. {
    2. "_scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAByQWQWx5bzRmTW9TeUNpNmVvN0E2dF9YQQ==",
    3. "took" : 1,
    4. "timed_out" : false,
    5. "terminated_early" : true,
    6. "_shards" : {
    7. "total" : 1,
    8. "successful" : 1,
    9. "skipped" : 0,
    10. "failed" : 0
    11. },
    12. "hits" : {
    13. "total" : {
    14. "value" : 3,
    15. "relation" : "eq"
    16. },
    17. "max_score" : 1.0,
    18. "hits" : [
    19. {
    20. "_index" : "book",
    21. "_type" : "_doc",
    22. "_id" : "2",
    23. "_score" : 1.0,
    24. "_source" : {
    25. "name" : "java编程思想",
    26. "description" : "java语言是世界第一编程语言,在软件开发领域使用人数最多。",
    27. "studymodel" : "201001",
    28. "price" : 68.6,
    29. "timestamp" : "2019-08-25 19:11:35",
    30. "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
    31. "tags" : [
    32. "java",
    33. "dev"
    34. ]
    35. }
    36. }
    37. ]
    38. }
    39. }

    每一次都带上上一次的_scroll_id。,接下来获取第三条数据。

    1. GET /_search/scroll
    2. {
    3. "scroll": "1m",
    4. "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAByQWQWx5bzRmTW9TeUNpNmVvN0E2dF9YQQ=="
    5. }

    成功获取第三条数据:

    1. {
    2. "_scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAByQWQWx5bzRmTW9TeUNpNmVvN0E2dF9YQQ==",
    3. "took" : 1,
    4. "timed_out" : false,
    5. "terminated_early" : true,
    6. "_shards" : {
    7. "total" : 1,
    8. "successful" : 1,
    9. "skipped" : 0,
    10. "failed" : 0
    11. },
    12. "hits" : {
    13. "total" : {
    14. "value" : 3,
    15. "relation" : "eq"
    16. },
    17. "max_score" : 1.0,
    18. "hits" : [
    19. {
    20. "_index" : "book",
    21. "_type" : "_doc",
    22. "_id" : "3",
    23. "_score" : 1.0,
    24. "_source" : {
    25. "name" : "spring开发基础",
    26. "description" : "spring 在java领域非常流行,java程序员都在用。",
    27. "studymodel" : "201001",
    28. "price" : 88.6,
    29. "timestamp" : "2019-08-24 19:11:35",
    30. "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
    31. "tags" : [
    32. "spring",
    33. "java"
    34. ]
    35. }
    36. }
    37. ]
    38. }
    39. }

  • 相关阅读:
    [远程Call]32位远程多参数带返回调用
    LeetCode-143. 重排链表-Java-medium
    [NOIP2015 提高组] 跳石头
    Spring系列文章:Bean的作⽤域
    【后端面经-数据库】Redis数据结构和底层数据类型
    java计算机毕业设计消防网站源码+系统+数据库+lw文档+mybatis+运行部署
    u盘删除的文件在哪里?u盘数据如何恢复?
    德国大学新突破:实现数千原子量子纠缠
    【Flink】FLink 设置 TaskManager 端口固定 或者 在一定范围
    【设计模式】工厂模式(Factory Pattern)
  • 原文地址:https://blog.csdn.net/FaithWh/article/details/126847076