iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 17
0

Day 17 Index Module


前言

前面兩天,我們大致上將data stream的用途、實際操作以及具體的設定介紹得差不多了。今天我們回過來,再補充一下關於index的一些操作,當初我們大致上只有講到index的介紹、基本設定以及如何將文件導入index,另外就是index template相關的設定。今天我們來進一步提到index上的一些額外設定,可以讓使用index以及設計上更有效率。

Index Block

Index Block意指可以設定Index阻擋一些功能,像是讀、改、寫等等。而這些block的操作,不需要預先設定,可以透過後面API操作去調整。

舉例來說,我們要讓demo-index不能寫入,可以這樣設定

PUT /demo-index/_block/write

而主要可以block有以下

  • metadata
    Disable metadata changes, such as closing the index.
  • read
    Disable read operations.
  • read_only
    Disable write operations and metadata changes.
  • write
    Disable write operations. However, metadata changes are still allowed.

Similarity module

Similarity module功用在於查詢時,要判斷document與查詢相似度的做法,其中可以設定index中各種自定義的similarity,主要呈現如下:

可以看到針對index的設定,我們定義了index中的similarity,並且定義了一個similarity的module。

當中包含他的類型以及一些標準化設定。

PUT /index
{
  "settings": {
    "index": {
      "similarity": {
        "my_similarity": {
          "type": "DFR",
          "basic_model": "g",
          "after_effect": "l",
          "normalization": "h2",
          "normalization.h2.c": "3.0"
        }
      }
    }
  }
}

接著我們將index中的mapping套上定義的similarity,就可以使這個mapping在查找時,套用這個方式計算分數。

PUT /index/_mapping
{
  "properties" : {
    "title" : { "type" : "text", "similarity" : "my_similarity" }
  }
}

而剛剛提到,similarity的基本設定,其實會根據演算法不同,會有一些不同設定,細節可以參考similarity type

預設則是bm25,也就是基於tf-idf的一個演算法,其他細節大家可以看一下,有機會再額外寫一篇來介紹跟NLP相關的計算分數查找方式!

而除了這些預設類型,elk也提供script式的,也就是你提供給他一套算分標準,可以用這套去計算,算是非常方便。

以下是官網中示範如何script計算tf-idf

PUT /index
{
  "settings": {
    "number_of_shards": 1,
    "similarity": {
      "scripted_tfidf": {
        "type": "scripted",
        "script": {
          "source": "double tf = Math.sqrt(doc.freq); double idf = Math.log((field.docCount+1.0)/(term.docFreq+1.0)) + 1.0; double norm = 1/Math.sqrt(doc.length); return query.boost * tf * idf * norm;"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "field": {
        "type": "text",
        "similarity": "scripted_tfidf"
      }
    }
  }
}

PUT /index/_doc/1
{
  "field": "foo bar foo"
}

PUT /index/_doc/2
{
  "field": "bar baz"
}

POST /index/_refresh

GET /index/_search?explain=true
{
  "query": {
    "query_string": {
      "query": "foo^1.7",
      "default_field": "field"
    }
  }
}

而這個自己寫script的方式,有一些限制如下:

Returned scores must be positive.
All other variables remaining equal, scores must not decrease when doc.freq increases.
All other variables remaining equal, scores must not increase when doc.length increases.

基本上就是分數要是正的;其他條件相同下,出現文件頻率越高分數不能低;另外文件長度越長分數不能越高

Index Sorting

index sorting,主要目的就是讓資料呈現的時候,按照設定的sort去呈現。舉例來說如果是一個員工資料index,我讓他用年齡去sort,並且desc,按順序就會年齡由高到低去呈現。

這種設定可以讓一些查找更加有效率,而具體的設定方式如下:

PUT demo-index
{
  "settings": {
    "index": {
      "sort.field": "date", 
      "sort.order": "desc"  
    }
  },
  "mappings": {
    "properties": {
      "date": {
        "type": "date"
      }
    }
  }
}

在設定中,我們將排序欄位設為date,並且使用降冪,如此一來就會按日期由大到小去排序

而這樣設定,具體上怎麼讓速度變快呢,官網說明如下

By default in Elasticsearch a search request must visit every document that match a query to retrieve the top documents sorted by a specified sort. Though when the index sort and the search sort are the same it is possible to limit the number of documents that should be visited per segment to retrieve the N top ranked documents globally. For example, let’s say we have an index that contains events sorted by a timestamp field:

預設來說elasticsearch會遍歷後,再進行特殊的排序。因此當查詢的sort以及index sort方式相同,就可以減少遍歷的數量,在取得N個的狀況下,就會比較快。

具體案例如下:

PUT events
{
  "settings": {
    "index": {
      "sort.field": "timestamp",
      "sort.order": "desc" 
    }
  },
  "mappings": {
    "properties": {
      "timestamp": {
        "type": "date"
      }
    }
  }
}
GET /events/_search
{
  "size": 10,
  "sort": [
    { "timestamp": "desc" }
  ]
}

這種查詢與index sort相同的情況下,並且限定N個數量(size = 10),就會減少運算時間。

另外若不需要知道具體所有數量,也可以透過設定關閉

GET /events/_search
{
  "size": 10,
  "sort": [ 
      { "timestamp": "desc" }
  ],
  "track_total_hits": false
}

這樣就會更加有效率,只會提取前N個。回傳的結果如下:

{
  "_shards": ...
   "hits" : {  
      "max_score" : null,
      "hits" : []
  },
  "took": 20,
  "timed_out": false
}

上一篇
Day 16 Use and Set DataStream
下一篇
Day 18 Ingest-1
系列文
親愛的,我把ElasticSearch上雲了30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言