天天看點

ElasticSearch7.3學習(二十二)----Text字段排序、Scroll分批查詢場景解析

1、Text字段排序

場景:資料庫中按照某個字段排序,sql隻需寫order by 字段名即可,如果es對一個

text field

進行排序,es中無法排序。因為文檔入反向索引表時,分詞存入,es無法知道此字段的真實值。這樣的結果往往不準确,因為分詞後是多個單詞,再排序就不是我們想要的結果了。

通常有兩種解決辦法:

  1. 将一個text field建立兩次索引,一個分詞,用來進行搜尋;一個不分詞,用來進行排序。
  2. mapping時設定

    fielddata:true

    ,按照第一個分詞進行字典序排序。這種方式也不是很準确,因為隻是按照第一個分詞進行排序,後續的分詞不會參與排序。fielddata:true的排序是對text内部分詞結果進行排序之後再進行外部排序的,效率低不推薦使用;

樣例如下:

首先建立索引

PUT /website
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword"
          }
        }
      },
      "content": {
        "type": "text",
        "fielddata": true
      },
      "post_date": {
        "type": "date"
      },
      "author_id": {
        "type": "long"
      }
    }
  }
}           

插入資料

PUT /website/_doc/1
{
  "title": "first article",
  "content": "this is my second article",
  "post_date": "2019-01-01",
  "author_id": 110
}

PUT /website/_doc/2
{
    "title": "second article",
    "content": "this is my second article",
     "post_date": "2019-01-01",
    "author_id": 110
}

PUT /website/_doc/3
{
     "title": "third article",
     "content": "this is my third article",
     "post_date": "2019-01-02",
     "author_id": 110
}           

搜尋,按照整個title的值進行排序

GET /website/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "title.keyword": {
        "order": "desc"
      }
    }
  ]
}           

結果如下:

ElasticSearch7.3學習(二十二)----Text字段排序、Scroll分批查詢場景解析

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

然後再看下"fielddata": true這種情況,對content進行排序

GET /website/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "content": {
        "order": "desc"
      }
    }
  ]
}           

結果如下:

ElasticSearch7.3學習(二十二)----Text字段排序、Scroll分批查詢場景解析

結果是以分詞後的第一個單詞進行排序,排序結果不準确,是以不推薦使用。

2、Scroll分批查詢

場景:下載下傳某一個索引中1億條資料,到檔案或是資料庫。

不能一下全查出來,這樣會造成系統記憶體溢出。是以使用scoll滾動搜尋技術,一批一批查詢。scoll搜尋會在第一次搜尋的時候,儲存一個當時的視圖快照,之後隻會基于該舊的視圖快照提供資料搜尋,如果這個期間資料變更,是不會讓使用者看到的。每次發送scroll請求,我們還需要指定一個scoll參數,指定一個時間視窗,每次搜尋請求隻要在這個時間視窗内能完成就可以了。

假如有三億條資料,這裡實際隻有3條

添加測試資料

PUT /book/_doc/1
{
  "name": "Bootstrap開發",
  "description": "Bootstrap是由Twitter推出的一個前台頁面開發css架構,是一個非常流行的開發架構,此架構內建了多種頁面效果。此開發架構包含了大量的CSS、JS程式代碼,可以幫助開發者(尤其是不擅長css頁面開發的程式人員)輕松的實作一個css,不受浏覽器限制的精美界面css效果。",
  "studymodel": "201002",
  "price": 38.6,
  "timestamp": "2019-08-25 19:11:35",
  "pic": "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
  "tags": [
    "bootstrap",
    "dev"
  ]
}
​
PUT /book/_doc/2
{
  "name": "java程式設計思想",
  "description": "java語言是世界第一程式設計語言,在軟體開發領域使用人數最多。",
  "studymodel": "201001",
  "price": 68.6,
  "timestamp": "2019-08-25 19:11:35",
  "pic": "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
  "tags": [
    "java",
    "dev"
  ]
}
​
PUT /book/_doc/3
{
  "name": "spring開發基礎",
  "description": "spring 在java領域非常流行,java程式員都在用。",
  "studymodel": "201001",
  "price": 88.6,
  "timestamp": "2019-08-24 19:11:35",
  "pic": "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
  "tags": [
    "spring",
    "java"
  ]
}           

搜尋

GET /book/_search?scroll=1m
{
  "query": {
    "match_all": {}
  },
  "size": 1
}           

首先擷取第一批次的資料,這裡隻傳回一條。

{
  "_scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAByQWQWx5bzRmTW9TeUNpNmVvN0E2dF9YQQ==",
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "book",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "Bootstrap開發",
          "description" : "Bootstrap是一個非常流行的開發架構。此開發架構可以幫助不擅長css頁面開發的程式人員輕松的實作一個css,不受浏覽器限制的精美界面css效果。",
          "studymodel" : "201002",
          "price" : 38.6,
          "timestamp" : "2019-08-25 19:11:35",
          "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
          "tags" : [
            "bootstrap",
            "dev"
          ]
        }
      }
    ]
  }
}           

可以看到擷取到了第一條的資料,獲得的結果裡面包含有一個scoll_id,下一次再發送scoll請求的時候,必須帶上這個scoll_id,接下來擷取第二條資料

GET /_search/scroll
{
    "scroll": "1m", 
    "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAByQWQWx5bzRmTW9TeUNpNmVvN0E2dF9YQQ=="
}           

擷取成功第二條資料

{
  "_scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAByQWQWx5bzRmTW9TeUNpNmVvN0E2dF9YQQ==",
  "took" : 1,
  "timed_out" : false,
  "terminated_early" : true,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "book",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "name" : "java程式設計思想",
          "description" : "java語言是世界第一程式設計語言,在軟體開發領域使用人數最多。",
          "studymodel" : "201001",
          "price" : 68.6,
          "timestamp" : "2019-08-25 19:11:35",
          "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
          "tags" : [
            "java",
            "dev"
          ]
        }
      }
    ]
  }
}           

每一次都帶上上一次的_scroll_id。,接下來擷取第三條資料。

GET /_search/scroll
{
    "scroll": "1m", 
    "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAByQWQWx5bzRmTW9TeUNpNmVvN0E2dF9YQQ=="
}           

成功擷取第三條資料:

{
  "_scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAByQWQWx5bzRmTW9TeUNpNmVvN0E2dF9YQQ==",
  "took" : 1,
  "timed_out" : false,
  "terminated_early" : true,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "book",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "name" : "spring開發基礎",
          "description" : "spring 在java領域非常流行,java程式員都在用。",
          "studymodel" : "201001",
          "price" : 88.6,
          "timestamp" : "2019-08-24 19:11:35",
          "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
          "tags" : [
            "spring",
            "java"
          ]
        }
      }
    ]
  }
}           

本文來自部落格園,作者:|舊市拾荒|,轉載請注明原文連結:https://www.cnblogs.com/xiaoyh/p/16163209.html