iT邦幫忙

2023 iThome 鐵人賽

DAY 8
0
Software Development

由淺入深來探討Elasticsearch,從基礎語法到底層相關原理系列 第 8

【Day 8】由淺入深來探討Elasticsearch - Object field type

  • 分享至 

  • xImage
  •  

在有些狀況中,我們在一個document中需要再多存其他的json object
例如:

PUT /company/_doc/1
{ 
  "region": "TW",
  "manager": { 
    "age":     30,
    "name": { 
      "first": "David",
      "last":  "Smith"
    }
  }
}

在document中,manager這個欄位本身也是儲存json格式
這樣的欄位就是object type field

object type一般比較常用的有以下幾種:

  • object
  • nested
  • join

object type

  • 一般在mapping設定時,沒有特別寫出來設定哪一種object的話就是預設object type
  • 因為Luncene沒有object這種對象的結構,因此會物件攤平後儲存
"region":             "TW",
"manager.age":        30,
"manager.name.first": "David",
"manager.name.last":  "Smith"

那乍看之下是沒有問題,但是如果今天換成這樣呢?

POST /employee/_doc
{
  "name": "Peter",
  "skill": [
    {
      "category": "front-end",
      "level": 10,
      "description": "senior"
    },
    {
      "category": "back-end",
      "level": 1,
      "description": "junior"
    }
    ]
}

我們存了一個document,今天他有包含兩個欄位name與skill
其中skill欄位是一個object type field
並且其中包含了兩個inner object,那經過扁平化後會長這樣

"skill.category": ["front-end", "back-end"],
"skill.level": [10, 1],
"skill.description": ["senior", "junior"]

有發現問題了嗎?

如果沒有的話,我們可以使用以下搜尋字句去查找

GET /employee/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "skill.level": {
              "lte": 9
            }
          }
        },
        {
          "match": {
            "name": "Peter"
          }
        },
        {
          "match": {
            "skill.category.keyword": "front-end"
          }
        }
      ]
    }
  }
}

看不懂沒關係,大意上是:

  • 以下的搜尋是必須符合must中設定的條件
  • 必須符合name為Peter並且我要找的分類是front-end
  • front-end領域中level低於9的

那應該會找不到資料吧~因為Peter的front-end有10分
但是ES會找到該筆資料,現在知道原因了嗎?
因為扁平化而導致資料失去關聯性
而為了解決這樣的問題object中的nested type可以處理這樣的類型

nested type

"type":  "nested"
  • 是為了維持array與對象之間的關係,能夠查詢到彼此之間的關係
  • 需要使用不同的查詢方法(在搜尋語法時會再介紹),分析與排序都是要用自己的語法
  • 因為Apache Lucene中沒有對象的觀念,所以是由隱藏文檔進行儲存,假如今天有一個文檔他的一個屬性內有10個數組,就會有額外文檔存入Apache Lucene底層,因此更耗資源
  • 為了避免記憶體不足,一個document中最多只能有1萬個nested JSON物件(跨欄位算)。但是可以透過index.mapping.nested_objects.limit去調整,但是不建議
  • 一般能添加到索引中的嵌套字段上限是50,可以靠index.mapping.nested_fields.limit增加,但是不推薦

在查詢時會再介紹有關nested type的部分,因為nested type需要使用不同的查詢方式~這邊有個觀念就好
明天會再介紹另一種object type: Join type


上一篇
【Day 7】由淺入深來探討Elasticsearch - Mapping
下一篇
【Day 9】由淺入深來探討Elasticsearch - Join type field
系列文
由淺入深來探討Elasticsearch,從基礎語法到底層相關原理30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言