Elasticsearch——叢集管理及文件CRUD

Dictator丶發表於2019-01-26

1. 叢集管理

Elasticsearch 提供了 cat api, 可以檢視叢集的資料

1.1 檢查叢集的健康情況

GET _cat/health?v
複製程式碼

返回結果:

epoch      timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1548510225 21:43:45  win-es  yellow          1         1      1   1    0    0        1             0                  -                 50.0%
複製程式碼

1.2 檢視叢集中有哪些索引

GET _cat/indices?v
複製程式碼

返回結果:

health status index   uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   .kibana sdht2-l3Q9SaK-neV9RKcQ   1   1          1            0      3.2kb          3.2kb
複製程式碼

2. 文件CRUD

2.1 新增商品:新增文件,建立索引

語法: PUT /index/type/id

PUT /ecommerce/product/1
{
  "name": "gaolujie yagao",
  "desc": "gaoxiao meibai",
  "price": 30,
  "producer": "gaolujie producer",
  "tags": ["meibai","fangzhu"]
}
複製程式碼

返回結果:

{
  "_index": "ecommerce",
  "_type": "product",
  "_id": "1",
  "_version": 1,
  "result": "created",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "created": true
}
複製程式碼

其餘兩條資料:

PUT /ecommerce/product/2
{
    "name" : "jiajieshi yagao",
    "desc" :  "youxiao fangzhu",
    "price" :  25,
    "producer" :      "jiajieshi producer",
    "tags": [ "fangzhu" ]
}

PUT /ecommerce/product/3
{
    "name" : "zhonghua yagao",
    "desc" :  "caoben zhiwu",
    "price" :  40,
    "producer" : "zhonghua producer",
    "tags": [ "qingxin" ]
}
複製程式碼

es會自動建立index和type,不需要提前建立,而且es預設會對document每個field都建立倒排索引,讓其可以被搜尋

2.2 查詢商品:檢索文件

語法: GET /index/type/id

GET /ecommerce/product/1
複製程式碼

返回結果:

{
  "_index": "ecommerce",
  "_type": "product",
  "_id": "1",
  "_version": 1,
  "found": true,
  "_source": {
    "name": "gaolujie yagao",
    "desc": "gaoxiao meibai",
    "price": 30,
    "producer": "gaolujie producer",
    "tags": [
      "meibai",
      "fangzhu"
    ]
  }
}
複製程式碼

2.3 修改商品:替換文件

PUT /ecommerce/product/1
{
    "name" : "jiaqiangban gaolujie yagao",
    "desc" :  "gaoxiao meibai",
    "price" :  30,
    "producer" :      "gaolujie producer",
    "tags": [ "meibai", "fangzhu" ]
}
複製程式碼

返回結果:

{
  "_index": "ecommerce",
  "_type": "product",
  "_id": "1",
  "_version": 2,
  "result": "updated",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "created": false
}
複製程式碼

替換方式有一個不好,即使必須帶上所有的field,才能去進行資訊的修改。例如:

PUT /ecommerce/product/1
{
    "name" : "jiaqiangban gaolujie yagao"
}
複製程式碼

執行 GET 檢視該文件,返回結果:

{
  "_index": "ecommerce",
  "_type": "product",
  "_id": "1",
  "_version": 3,
  "found": true,
  "_source": {
    "name": "jiaqiangban gaolujie yagao"
  }
}
複製程式碼

返回結果中只有 name 欄位

2.4 修改商品:更新文件

注意語法, 有 doc

POST /ecommerce/product/1/_update
{
  "doc": {
    "name": "jiaqiangban gaolujie yagao"
  }
}
複製程式碼

返回結果:

{
  "_index": "ecommerce",
  "_type": "product",
  "_id": "1",
  "_version": 7,
  "found": true,
  "_source": {
    "name": "jiaqiangban gaolujie yagao",
    "desc": "gaoxiao meibai",
    "price": 30,
    "producer": "gaolujie producer",
    "tags": [
      "meibai",
      "fangzhu"
    ]
  }
}
複製程式碼

2.5 刪除文件

語法: DELETE /ecommerce/producer/1

DELETE /ecommerce/producet/1
複製程式碼

返回結果:

{
  "found": false,
  "_index": "ecommerce",
  "_type": "producet",
  "_id": "1",
  "_version": 1,
  "result": "not_found",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  }
}
複製程式碼

3. 搜素方式

3.1 query string search

GET /ecommerce/product/_search
複製程式碼

返回結果:

  • took:耗費了幾毫秒

  • timed_out:是否超時,這裡是沒有

  • _shards:資料拆成了5個分片,所以對於搜尋請求,會打到所有的primary

  • shard(或者是它的某個replica shard也可以)

  • hits.total:查詢結果的數量,3個document

  • hits.max_score:score的含義,就是document對於一個search的相關度的匹配分數,越相關,就越匹配,分數也高

  • hits.hits:包含了匹配搜尋的document的詳細資料

    {
      "took": 3,             # 耗費幾毫秒
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
      },
      "hits": {
        "total": 3,
        "max_score": 1,
        "hits": [
          {
            "_index": "ecommerce",
            "_type": "product",
            "_id": "2",
            "_score": 1,
            "_source": {
              "name": "jiajieshi yagao",
              "desc": "youxiao fangzhu",
              "price": 25,
              "producer": "jiajieshi producer",
              "tags": [
                "fangzhu"
              ]
            }
          },
          {
            "_index": "ecommerce",
            "_type": "product",
            "_id": "1",
            "_score": 1,
            "_source": {
              "name": " aolujie yagao",
              "desc": "gaoxiao meibai",
              "price": 30,
              "producer": "gaolujie producer",
              "tags": [
                "meibai",
                "fangzhu"
              ]
            }
          },
          {
            "_index": "ecommerce",
            "_type": "product",
            "_id": "3",
            "_score": 1,
            "_source": {
              "name": "zhonghua yagao",
              "desc": "caoben zhiwu",
              "price": 40,
              "producer": "zhonghua producer",
              "tags": [
                "qingxin"
              ]
            }
          }
        ]
      }
    }
    複製程式碼

query string search的由來,因為search引數都是以http請求的query string來附帶的

搜尋商品名稱中包含yagao的商品,而且按照售價降序排序

GET /ecommerce/product/_search?q=name:yagao&sort=price:desc
複製程式碼

返回結果:

{
  "took": 18,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 3,
    "max_score": null,
    "hits": [
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "3",
        "_score": null,
        "_source": {
          "name": "zhonghua yagao",
          "desc": "caoben zhiwu",
          "price": 40,
          "producer": "zhonghua producer",
          "tags": [
            "qingxin"
          ]
        },
        "sort": [
          40
        ]
      },
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "1",
        "_score": null,
        "_source": {
          "name": " aolujie yagao",
          "desc": "gaoxiao meibai",
          "price": 30,
          "producer": "gaolujie producer",
          "tags": [
            "meibai",
            "fangzhu"
          ]
        },
        "sort": [
          30
        ]
      },
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "2",
        "_score": null,
        "_source": {
          "name": "jiajieshi yagao",
          "desc": "youxiao fangzhu",
          "price": 25,
          "producer": "jiajieshi producer",
          "tags": [
            "fangzhu"
          ]
        },
        "sort": [
          25
        ]
      }
    ]
  }
}
複製程式碼

適用於臨時的在命令列使用一些工具,比如curl,快速的發出請求,來檢索想要的資訊;但是如果查詢請求很複雜,是很難去構建的 在生產環境中,幾乎很少使用query string search

3.2 quert DSL

DSL: Domain Specified Language 特定領域的語言

http request body: 請求體,可以用 json 的格式來構建查詢語法,比較方便。可以構建各種複雜的語法。

  • 查詢所有商品

    GET /ecommerce/product/_search
    {
      "query": {
        "match_all": {}
      }
    }
    複製程式碼

返回結果同上

  • 搜尋商品名稱中包含yagao的商品,而且按照售價降序排序

    GET /ecommerce/product/_search
    {
      "query": {
        "match": {
          "name": "yagao"
        }
      },
      "sort": [
        {
          "price": "desc"
        }
      ]
    }
    複製程式碼
  • 分頁查詢商品

    假設每頁一個商品,查詢第二頁的商品

    GET /ecommerce/product/_search
    {
      "query": {
        "match_all": {}
      },
      "from": 1,
      "size": 1
    }
    複製程式碼
  • 指定查詢後返回的欄位

    GET /ecommerce/product/_search
    {
      "query": {
        "match_all": {}
      },
      "_source": ["name", "price"]
    }
    複製程式碼

返回結果:

{
  "took": 11,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 3,
    "max_score": 1,
    "hits": [
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "2",
        "_score": 1,
        "_source": {
          "price": 25,
          "name": "jiajieshi yagao"
        }
      },
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "1",
        "_score": 1,
        "_source": {
          "price": 30,
          "name": " aolujie yagao"
        }
      },
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "3",
        "_score": 1,
        "_source": {
          "price": 40,
          "name": "zhonghua yagao"
        }
      }
    ]
  }
}
複製程式碼

3.3 query filter

查詢名稱包含 yagao, 價格大於25的商品

GET /ecommerce/product/_search
{
  "query": {
    "bool": {
      "must": {
        "match": {
          "name": "yagao"
        }
      },
      "filter": {
        "range": {
          "price": {
            "gt": 25
          }
        }
      }
    }
  }
}
複製程式碼

3.4 full-text search 全文搜尋

先增加一條資料,producer 欄位中包含 yagao producer這兩個詞:

PUT /ecommerce/product/4
{
  "name": "special yagao",
  "desc": "",
  "proce": 50,
  "producer": "special yagao producer",
  "tags": ["meibai"]
}
複製程式碼

查詢:

GET /ecommerce/product/_search
{
  "query": {
    "match": {
      "producer": "yagao producer"
    }
  }
}
複製程式碼

返回結果:

{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": 0.70293105,
    "hits": [
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "4",
        "_score": 0.70293105,
        "_source": {
          "producer": "special yagao producer"
        }
      },
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "1",
        "_score": 0.25811607,
        "_source": {
          "name": " aolujie yagao",
          "desc": "gaoxiao meibai",
          "price": 30,
          "producer": "gaolujie producer",
          "tags": [
            "meibai",
            "fangzhu"
          ]
        }
      },
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "3",
        "_score": 0.25811607,
        "_source": {
          "name": "zhonghua yagao",
          "desc": "caoben zhiwu",
          "price": 40,
          "producer": "zhonghua producer",
          "tags": [
            "qingxin"
          ]
        }
      },
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "2",
        "_score": 0.1805489,
        "_source": {
          "name": "jiajieshi yagao",
          "desc": "youxiao fangzhu",
          "price": 25,
          "producer": "jiajieshi producer",
          "tags": [
            "fangzhu"
          ]
        }
      }
    ]
  }
}
複製程式碼

從結果中可以看出, 新增的資料包含 yagao 和 producer 這兩個詞,所以評分最高。

3.5 phrase query 短語查詢

跟全文檢索相反,全文檢索會將輸入的搜尋串拆解開來,去倒排索引裡面去一一匹配,只要能匹配上任意一個拆解後的單詞,就可以作為結果返回

phrase search,要求輸入的搜尋串,必須在指定的欄位文字中,完全包含一模一樣的,才可以算匹配,才能作為結果返回

GET /ecommerce/product/_search
{
  "query": {
    "match_phrase": {
      "producer": "yagao producer"
    }
  }
}
複製程式碼

返回結果:

{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.70293105,
    "hits": [
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "4",
        "_score": 0.70293105,
        "_source": {
          "producer": "special yagao producer"
        }
      }
    ]
  }
}
複製程式碼

3.6 highlight search 高亮搜尋結果

GET /ecommerce/product/_search
{
  "query": {
    "match": {
      "producer": "producer"
    }
  },
  "highlight": {
    "fields": {
      "producer": {}
    }
  }
}
複製程式碼

返回結果:

{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": 0.25811607,
    "hits": [
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "1",
        "_score": 0.25811607,
        "_source": {
          "name": "gaolujie yagao",
          "desc": "gaoxiao meibai",
          "price": 30,
          "producer": "gaolujie producer",
          "tags": [
            "meibai",
            "fangzhu"
          ]
        },
        "highlight": {
          "producer": [
            "gaolujie <em>producer</em>"
          ]
        }
      },
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "3",
        "_score": 0.25811607,
        "_source": {
          "name": "zhonghua yagao",
          "desc": "caoben zhiwu",
          "price": 40,
          "producer": "zhonghua producer",
          "tags": [
            "qingxin"
          ]
        },
        "highlight": {
          "producer": [
            "zhonghua <em>producer</em>"
          ]
        }
      },
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "2",
        "_score": 0.1805489,
        "_source": {
          "name": "jiajieshi yagao",
          "desc": "youxiao fangzhu",
          "price": 25,
          "producer": "jiajieshi producer",
          "tags": [
            "fangzhu"
          ]
        },
        "highlight": {
          "producer": [
            "jiajieshi <em>producer</em>"
          ]
        }
      },
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "4",
        "_score": 0.14638957,
        "_source": {
          "producer": "special yagao producer"
        },
        "highlight": {
          "producer": [
            "special yagao <em>producer</em>"
          ]
        }
      }
    ]
  }
}
複製程式碼

4. 簡單聚合

先對tag設定可以進行聚合分析,否則會報錯

將文字field的fielddata屬性設定為true

PUT /ecommerce/product/_mapping
{
  "properties": {
    "tags": {
      "type": "text",
      "fielddata": true
    }
  }
}
複製程式碼

4.1 計算每個tag下的商品數量

聚合查詢語法:

GET /ecommerce/product/_search
{
  "aggs": {
    "group_by_tags": {
      "terms": {
        "field": "tags"
      }
    }
  }
}
複製程式碼

返回結果:

{
  "took": 28,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": 1,
    "hits": [
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "2",
        "_score": 1,
        "_source": {
          "name": "jiajieshi yagao",
          "desc": "youxiao fangzhu",
          "price": 25,
          "producer": "jiajieshi producer",
          "tags": [
            "fangzhu"
          ]
        }
      },
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "4",
        "_score": 1,
        "_source": {
          "name": "special yagao",
          "desc": "",
          "price": 50,
          "producer": "special yagao producer",
          "tags": [
            "meibai"
          ]
        }
      },
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "1",
        "_score": 1,
        "_source": {
          "name": "gaolujie yagao",
          "desc": "gaoxiao meibai",
          "price": 30,
          "producer": "gaolujie producer",
          "tags": [
            "meibai",
            "fangzhu"
          ]
        }
      },
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "3",
        "_score": 1,
        "_source": {
          "name": "zhonghua yagao",
          "desc": "caoben zhiwu",
          "price": 40,
          "producer": "zhonghua producer",
          "tags": [
            "qingxin"
          ]
        }
      }
    ]
  },
  "aggregations": {
    "group_by_tags": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "fangzhu",
          "doc_count": 2
        },
        {
          "key": "meibai",
          "doc_count": 2
        },
        {
          "key": "qingxin",
          "doc_count": 1
        }
      ]
    }
  }
}
複製程式碼

可以看到,返回結果包含了每條文件的詳細資訊,如果只想要聚合結果,查詢時設定 size=0

GET /ecommerce/product/_search
{
  "size": 0,
  "aggs": {
    "group_by_tags": {
      "terms": {
        "field": "tags"
      }
    }
  }
}
複製程式碼

返回結果:

{
  "took": 5,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "group_by_tags": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "fangzhu",
          "doc_count": 2
        },
        {
          "key": "meibai",
          "doc_count": 2
        },
        {
          "key": "qingxin",
          "doc_count": 1
        }
      ]
    }
  }
}
複製程式碼

可以看到返回結果中就沒有詳細資訊了,只有聚合資訊

4.2 對名稱中包含yagao的商品,計算每個tag下的商品數量

GET /ecommerce/product/_search
{
  "size": 0,
  "query": {
    "match": {
      "name": "yagao"
    }
  },
  "aggs": {
    "group_by_tags": {
      "terms": {
        "field": "tags"
      }
    }
複製程式碼

返回結果:

{
  "took": 13,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "group_by_tags": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "fangzhu",
          "doc_count": 2
        },
        {
          "key": "meibai",
          "doc_count": 2
        },
        {
          "key": "qingxin",
          "doc_count": 1
        }
      ]
    }
  }
}
複製程式碼

4.3 先分組,再算每組的平均值,計算每個tag下的商品的平均價格

計算每個 tag 下的平均價格,就要在 tag 的分組的裡面再進行分組

GET /ecommerce/product/_search
{
  "size": 0,
  "aggs": {
    "group_by_tags": {
      "terms": {
        "field": "tags"
      },
      "aggs": {
        "avg_price": {
          "avg": {
            "field": "price"
          }
        }
      }
    }
  }
}
複製程式碼

返回結果:

{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "group_by_tags": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "fangzhu",
          "doc_count": 2,
          "avg_price": {
            "value": 27.5
          }
        },
        {
          "key": "meibai",
          "doc_count": 2,
          "avg_price": {
            "value": 40
          }
        },
        {
          "key": "qingxin",
          "doc_count": 1,
          "avg_price": {
            "value": 40
          }
        }
      ]
    }
  }
}
複製程式碼

4.4 計算每個tag下的商品的平均價格,並且按照平均價格降序排序

再分組裡面寫排序規則

GET /ecommerce/product/_search
{
  "size": 0, 
  "aggs": {
    "group_by_tags": {
      "terms": {
        "field": "tags",
        "order": {
          "avg_price": "desc"
        }
      },
      "aggs": {
        "avg_price": {
          "avg": {
            "field": "price"
          }
        }
      }
    }
  }
}
複製程式碼

返回結果:

{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "group_by_tags": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "meibai",
          "doc_count": 2,
          "avg_price": {
            "value": 40
          }
        },
        {
          "key": "qingxin",
          "doc_count": 1,
          "avg_price": {
            "value": 40
          }
        },
        {
          "key": "fangzhu",
          "doc_count": 2,
          "avg_price": {
            "value": 27.5
          }
        }
      ]
    }
  }
}
複製程式碼

4.5 按照指定的價格範圍區間進行分組,然後在每組內再按照tag進行分組,最後再計算每組的平均價格

GET /ecommerce/product/_search
{
  "size": 0,
  "aggs": {
    "group_by_price": {
      "range": {
        "field": "price",
        "ranges": [
          {
            "from": 0,
            "to": 20
          },
          {
            "from": 20,
            "to": 40
          },
          {
            "from": 40,
            "to": 60
          }
        ]
      },
      "aggs": {
        "group_by_tags": {
          "terms": {
            "field": "tags",
            "order": {
              "avg_price": "desc"
            }
          },
          "aggs": {
            "avg_price": {
              "avg": {
                "field": "price"
              }
            }
          }
        }
      }
    }
  }
}
複製程式碼

返回結果:

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "group_by_price": {
      "buckets": [
        {
          "key": "0.0-20.0",
          "from": 0,
          "to": 20,
          "doc_count": 0,
          "group_by_tags": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": []
          }
        },
        {
          "key": "20.0-40.0",
          "from": 20,
          "to": 40,
          "doc_count": 2,
          "group_by_tags": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "meibai",
                "doc_count": 1,
                "avg_price": {
                  "value": 30
                }
              },
              {
                "key": "fangzhu",
                "doc_count": 2,
                "avg_price": {
                  "value": 27.5
                }
              }
            ]
          }
        },
        {
          "key": "40.0-60.0",
          "from": 40,
          "to": 60,
          "doc_count": 2,
          "group_by_tags": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "meibai",
                "doc_count": 1,
                "avg_price": {
                  "value": 50
                }
              },
              {
                "key": "qingxin",
                "doc_count": 1,
                "avg_price": {
                  "value": 40
                }
              }
            ]
          }
        }
      ]
    }
  }
}
複製程式碼

相關文章