Могу ли я создать документ с API обновления, если документ еще не существует?
У меня очень простой вопрос:
Я хочу обновить несколько документов до elasticsearch. Иногда документ уже существует, но иногда нет. Я не хочу использовать запрос получения, чтобы проверить наличие документа (это уменьшает мою производительность). Я хочу использовать непосредственно мой запрос на обновление, чтобы индексировать документ напрямую, если он еще не существует.
Я знаю, что мы можем использовать upsert для создания не существующего поля при обновлении документа, но это не то, что я хочу. Я хочу индексировать документ, если он не существует. Я не знаю, может ли upsert это сделать.
Можете ли вы дать мне разъяснения?
Спасибо заранее!
Ответы
Ответ 1
Это выполнимо, используя обновление api. Это требует, чтобы вы определяли идентификатор каждого документа, поскольку для обновления api требуется идентификатор документа для определения его присутствия.
С учетом индекса, созданного со следующими документами:
PUT /cars/car/1
{ "color": "blue", "brand": "mercedes" }
PUT /cars/car/2
{ "color": "blue", "brand": "toyota" }
Мы можем получить функциональность upsert, которую вы хотите, используя обновление api со следующим вызовом api.
POST /cars/car/3/_update
{
"doc": {
"color" : "brown",
"brand" : "ford"
},
"doc_as_upsert" : true
}
Этот вызов api добавит документ в индекс, поскольку он не существует.
Выполняя вызов второй раз после изменения цвета автомобиля, обновите документ, а не создайте новый документ.
POST /cars/car/3/_update
{
"doc": {
"color" : "black",
"brand" : "ford"
},
"doc_as_upsert" : true
}
Ответ 2
AFAIK, когда вы индексируете документы (с помощью PUT-вызова), существующая версия заменяется более новой версией. Если документ не существует, он создается. Нет необходимости проводить различие между INSERT и UPDATE в ElasticSearch.
ОБНОВЛЕНИЕ. В соответствии с документацией, если вы используете op_type = create или специальную _create версию индексационного вызова, тогда любой вызов для документ, который уже существует, завершится с ошибкой.
Цитата из документации:
Here is an example of using the op_type parameter:
$ curl -XPUT 'http://localhost:9200/twitter/tweet/1?op_type=create' -d '{
"user" : "kimchy",
"post_date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}'
Another option to specify create is to use the following uri:
$ curl -XPUT 'http://localhost:9200/twitter/tweet/1/_create' -d '{
"user" : "kimchy",
"post_date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}'
Ответ 3
От elasticsearch-model v0.1.4, upserts не поддерживаются. Я смог обойти это, создав пользовательский обратный вызов.
after_commit on: :update do
begin
__elasticsearch__.update_document
rescue Elasticsearch::Transport::Transport::Errors::NotFound
__elasticsearch__.index_document
end
end
Ответ 4
Для использования большого API
bulks.push({
update: {
_index: 'index',
_type: 'type',
_id: id
}
});
bulks.push({"doc_as_upsert":true, "doc": your_doc});