2012-04-17 34 views
7

Digamos que tengo un tipo tag en un índice Elasticsearch, con la siguiente asignación:¿Cómo actualizo varios elementos en ElasticSearch?

{ 
    "tag": { 
     "properties": { 
      "tag": {"type": "string", "store": "yes"}, 
      "aliases": {"type": "string"} 
     } 
    } 
} 

Cada entrada es una etiqueta, y una serie de alias para esa etiqueta. He aquí un ejemplo de ítem:

{ 
    "word": "weak", 
    "aliases": ["anemic", "anaemic", "faint", "flimsy"] 
} 

De vez en cuando, quiero añadir palabras nuevas etiquetas con sus alias, y añadir nuevos alias a las palabras de etiquetas existentes.

Agregar nuevas palabras de etiqueta con sus alias es fácil, es solo un documento nuevo. Sin embargo, ¿cómo puedo agregar nuevos alias a las palabras de etiqueta existentes de una manera sensata?

Sé que puedo buscar la palabra clave, obtener su documento, buscar si el alias ya existe en la matriz de alias, si no agregarlo, que guardar. Sin embargo, esto no parece una buena solución.

¿Hay alguna manera de hacer una actualización masiva?

Respuesta

7

El almacenamiento subyacente de búsqueda elástica, Lucene, no tiene una operación de actualización. Por lo tanto, todas las actualizaciones se realizan buscando el registro, eliminando la versión anterior y agregando la nueva versión. En elasticsearch, puede guardar un poco en mover registros hasta el final al cliente usando Update API. Aún así, sería necesario encontrar el registro. Lo que probablemente desee es Update by query pero, por desgracia, aún no está implementado.

+1

La actualización por consulta aún no se ha agregado a Elastic, pero existe un [complemento] (https://github.com/yakaz/elasticsearch-action-updatebyquery/). –

+1

A partir de Elasticsearch 2.3, la actualización por consulta está disponible - https://www.elastic.co/guide/en/elasticsearch/reference/2.3/docs-update-by-query.html – PhaedrusTheGreek

2

Elastic Search tiene un Update API. Con esa API puede hacer lo siguiente:

curl -XPOST 'localhost:9200/test/tag/weak/_update' -d '{ 
    "script" : "ctx._source.aliases += faint" 
}' 
+0

Hola Eric, esto es para actualización de documento único ¿verdad? –

+0

¿Puede decirme cómo puedo implementar la actualización de un solo registro en php? –

0

Además, si agrega el mismo valor con la misma identificación, actualizará automáticamente los datos anteriores.

6

probar este usando _bulk:

http://127.0.0.1:9200/myindex/type/_bulk 
{ 
"update": { 
    "_index": "myindex", 
    "_type": "type", 
    "_id": "myid" 
} 
}{ 
"doc": { 
    "field": "new value" 
} 
}{ 
"update": { 
    "_index": "myindex", 
    "_type": "type", 
    "_id": "id" 
} 
}{ 
"doc": { 
    "field": "new value" 
} 
} 
0

API a granel de Elasticsearch se pueden utilizar para las solicitudes de actualización, así, al menos por el cliente Java.

List list = new Arraylist(); 
list.add("hello"); 
BulkProcessor bulk = new BulkProcessor(); 
UpdateRequest update = new UpdateRequest("index", "type", "id1"); 
update.script("ctx._source.aliases+= newaliases"); //dynamic script 
update.addScriptParam("newaliases", list); 
bulk.add(update); 

Tenga en cuenta que scripting dinámico está deshabilitada en las nuevas versiones de elasticsearch. O habilite eso o use scripts precompilados para usar esta característica.

0

Puede hacer lo mismo utilizando Spring Java Client utilizando el siguiente código. Las siguientes son las dependencias usadas en el código.

import org.elasticsearch.action.update.UpdateRequest; 

import org.elasticsearch.index.query.QueryBuilder; 

import org.springframework.data.elasticsearch.core.query.UpdateQuery; 

import org.springframework.data.elasticsearch.core.query.UpdateQueryBuilder; 

private UpdateQuery updateExistingDocument(String Id) { 
    // Add updatedDateTime, CreatedDateTime, CreateBy, UpdatedBy field in existing documents in Elastic Search Engine 
    UpdateRequest updateRequest = new UpdateRequest().doc("UpdatedDateTime", new Date(), "CreatedDateTime", new Date(), "CreatedBy", "admin", "UpdatedBy", "admin"); 

    // Create updateQuery 
    UpdateQuery updateQuery = new UpdateQueryBuilder().withId(Id).withClass(ElasticSearchDocument.class).build(); 
    updateQuery.setUpdateRequest(updateRequest); 

    // Execute update 
    elasticsearchTemplate.update(updateQuery); 
} 
2

Esto funciona para mí.

input_list.dat:

{ "index" : { "_index": "my_index", "_type": "my_type", "_id": "existing-value" } } 

{ "Field_to_update": "New_Value" } 

{ "index" : { "_index": "my_index", "_type": "my_type", "_id": "existing_value" } } 

{ "Field_to_update": "New_Value" } 

Comando:

curl -k -XPOST 'https://my_host:9200/my_url/_bulk' --data-binary "@input_list.dat"; echo 
+0

¡Gracias, funciona para mí! Usando Elastic Search 5.4 –

1

Elasticsearch 2.3.0 introdujo el Update By Query API como parte de la Reindex API tan esperado.

A modo de ejemplo, aquí es cómo se puede actualizar todos los documentos para eliminar un campo determinado si existe:

POST /myindex/mytype/_update_by_query 
{ 
    "script": { 
    "inline": "ctx._source.remove(\"remove\")" 
    }, 
    "query": { 
    "exists": { 
     "field": "remove" 
    } 
    } 
} 

El ejemplo anterior utiliza secuencias de comandos en línea, así que asegúrese de activarlo en elasticsearch.yml con script.inline: on.

Cuestiones relacionadas