Как выполнить упругий поиск _update_by_query, используя безболезненный скрипт - для сложных условий - PullRequest
0 голосов
/ 27 мая 2018

Можете ли вы предложить, как обновить документы (используя сценарий - я думаю, безболезненно), основанный на полях условий?

Его цель состоит в том, чтобы добавлять / удалять значения из документа

, поэтомуесли у меня есть эти входные документы:

doc //1st
{
   "Tags":["foo"],
   "flag":"true"
}


doc //2nd
{
   "flag":"true"
}

doc //3rd
{
   "Tags": ["goo"],
   "flag":"false"
}

И я хочу выполнить что-то вроде этого:

Обновить все документы, которые имеют «flag = true», с помощью:

  • Добавлены теги: «me», «one»
  • Удалены теги: «goo», «foo»

, поэтому ожидаемый результат должен быть примерно таким:

doc //1st
{
   "Tags":["me","one"],
   "flag":"true"
}


doc //2nd
{
   "Tags":["me","one"],
   "flag":"true"
}

doc //3rd
{
   "Tags": ["goo"],
   "flag":"false"
}

1 Ответ

0 голосов
/ 27 мая 2018

Создать сопоставление:

PUT documents
{
    "mappings": {
        "document": {
            "properties": {
                "tags": {
                    "type": "keyword",
                    "index": "not_analyzed"
                },
                "flag": {
                    "type": "boolean"
                }
            }
        }
    }
}

Вставить первый документ:

PUT documents/document/1
{
    "tags":["foo"],
    "flag": true
}

Вставить второй документ (имейте в виду, что для пустых тегов я указал массив пустых тегов, потому что если вы этого не сделаете, тоесть поле, которое вам нужно проверить в скрипте. Поле существует):

PUT documents/document/2
{
    "tags": [],
    "flag": true
}

Добавьте третий документ:

PUT documents/document/3
{
    "tags": ["goo"],
    "flag": false
}

И затем запустите _update_by_query, который имеет два массива в качестве параметров один длядобавляемые элементы и один для удаляемых элементов:

POST documents/_update_by_query 
{
    "script": {
        "inline": "for(int i = 0; i < params.add_tags.size(); i++) { if(!ctx._source.tags.contains(params.add_tags[i].value)) { ctx._source.tags.add(params.add_tags[i].value)}} for(int i = 0; i < params.remove_tags.size(); i++) { if(ctx._source.tags.contains(params.remove_tags[i].value)){ctx._source.tags.removeAll(Collections.singleton(params.remove_tags[i].value))}}",
        "params": {
            "add_tags": [
                {"value": "me"},
                {"value": "one"}
            ],
            "remove_tags": [
                {"value": "goo"},
                {"value": "foo"}
            ]
        }
    },
    "query": {
        "bool": {
            "must": [
                {"term": {"flag": true}}
            ]
        }
    }
}

Если вы затем выполните следующий поиск:

GET documents/_search

, вы получите следующий результат (который, я думаю, то, что вы хотите):

{
    "took": 1,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": 3,
        "max_score": 1,
        "hits": [{
                "_index": "documents",
                "_type": "document",
                "_id": "2",
                "_score": 1,
                "_source": {
                    "flag": true,
                    "tags": [
                        "me",
                        "one"
                    ]
                }
            },
            {
                "_index": "documents",
                "_type": "document",
                "_id": "1",
                "_score": 1,
                "_source": {
                    "flag": true,
                    "tags": [
                        "me",
                        "one"
                    ]
                }
            },
            {
                "_index": "documents",
                "_type": "document",
                "_id": "3",
                "_score": 1,
                "_source": {
                    "tags": [
                        "goo"
                    ],
                    "flag": false
                }
            }
        ]
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...