Elasticsearch腳本更新嵌套類型

  • 數據樣例

索引名:nested
類型:doc1

{
    "detail": [
        {
            "name": "美團",
            "nid": 1200
        }
    ],
    "id": 1
}
  • 添加
    POST /nested/doc1/1/_update
{
    "script": {
        "lang": "painless",
        "source": "ctx._source.detail.add(params.data);",
        "params": {
            "data": {
                "name": "百度",
                "nid": 1300
            }
        }
    }
}

# 數據:
{
   "_index": "nested",
    "_type": "doc1",
    "_id": "1",
    "_score": 1.0,
    "_source": {
        "detail": [
            {
                "name": "美團",
                "nid": 1200
            },
            {
                "name": "百度",
                "nid": 1300
            }
        ],
        "id": 1
    }
}
  • 修改
    POST /nested/doc1/1/_update
{
    "script": {
        "lang": "painless",
        "source": "for(e in ctx._source.detail){if (e.name == params.name) {e.nid = params.nid;}}",
        "params": {
        	"name": "百度",
        	"nid": 1500
        }
    }
}
  • 刪除

POST /nested/doc1/1/_update

{
    "script": {
        "lang": "painless",
        "source": "ctx._source.detail.removeIf(it -> it.nid ==params.nid);if(ctx._source.detail.length == 0){ctx.op='delete'}",
        "params":{
        	"nid": 1200
        }
    }
}

# 刪除後
{
    "_index": "nested",
    "_type": "doc1",
    "_id": "1",
    "_score": 1,
    "_source": {
        "detail": [
            {
                "name": "百度",
                "nid": 1500
            }
        ],
        "id": 1
    }
}

這個腳本先刪除detail中nid=1200的元素,然後判斷如果detail長度爲0則刪除這條數據。
如果指定的nid不存在,也會返回200,但數據的版本號+1

  • 查詢

GET /nested/doc1/_search

{
    "query": {
        "nested": {
            "path": "detail",
            "query": {
                "term": {
                    "detail.nid": 1500
                }
            },
            "inner_hits": {}  # 返回嵌套查詢命中的文檔,可像普通查詢那樣添加from,size,_source等參數
        }
    }
}
  • 使用腳本來獲取每條數據中嵌套類型數組的長度
{
    "query": {
        "match_all": {}
    },
    "script_fields": {
        "detail_count": {  # 名稱自定義
            "script": {
                "lang": "painless",
                "source": "params['_source']['detail'].length"
            }
        }
    },
    "size": 100
}

params['_source']doc['xxx']的區別:

  • doc僅用於獲取簡單的(一個鍵對應一個值)、不分析的字段的值,像嵌套類型、文本類型等是不能用的。因此查詢會緩存,速度快,但也意味着更多的內存消耗。
  • params['_source']每次使用都要加載和解析,所以速度慢。

推薦使用doc,不能用再使用params。

注意
腳本中應避免使用硬編碼,即使用類似下面的編寫方式:
"source": "for(e in ctx._source.detail){if (e.name == '百度') {e.nid = 1500;}}",這將導致腳本每次運行之前都要進行編譯解析等工作,應當使用params參數。如果腳本是固定的,可將腳本保存在es中,後續只需要傳入腳本id和參數即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章