web-dev-qa-db-fra.com

Comment mettre à jour plusieurs documents correspondant à une requête dans elasticsearch

J'ai des documents qui ne contiennent que des champs "url" (analysé) et "respsize" (non analysé) au début. Je souhaite mettre à jour les documents qui correspondent à l'URL et ajouter un nouveau champ "catégorie" Je veux dire; Au premier doc1:

{
 "url":"http://stackoverflow.com/users/4005632/mehmet-yener-yilmaz",
 "respsize":"500"
}

J'ai des données externes et je sais que "stackoverflow.com" appartient à la catégorie 10, Et j'ai besoin de mettre à jour le document et de lui donner l'aspect suivant:

{
 "url":"http://stackoverflow.com/users/4005632/mehmet-yener-yilmaz",
 "respsize":"500",
 "category":"10"
}

Bien sûr, je vais faire cela pour tous les documents dont les champs d'URL ont "stackoverflow.com" devez utiliser _update api avec le numéro _version pour le vérifier, mais ne pouvez pas composer la requête DSL .EDIT Je lance ceci et cela fonctionne bien: enter image description here Mais les documents n'ont pas changé .. enter image description here

Bien que le résultat de la requête semble vrai, un nouveau champ n’a pas été ajouté à la documentation, doit être actualisé, etc.?

17
user4005632

Pour ce faire, vous pouvez utiliser le plug-in update by query plugin . L'idée est de sélectionner tous les documents sans category et dont url correspond à une certaine chaîne et d'ajouter la catégorie souhaitée.

curl -XPOST 'localhost:9200/webproxylog/_update_by_query' -d '
{
  "query": {
    "filtered": {
      "filter": {
        "bool": {
          "must": [
            {
              "term": {
                "url": "stackoverflow.com"
              }
            },
            {
              "missing": {
                "field": "category"
              }
            }
          ]
        }
      }
    }
  },
  "script" : "ctx._source.category = \"10\";"
}'

Après avoir exécuté ceci, tous vos documents avec url: stackoverflow.com qui n'ont pas de catégorie obtiendront category: 10. Vous pouvez réexécuter la même requête ultérieurement pour corriger les nouveaux documents stackoverflow.com qui ont été indexés entre-temps.

Assurez-vous également d'activer les scripts dans elasticsearch.yml et de redémarrer ES: 

script.inline: on 
script.indexed: on

Dans le script, vous êtes libre d'ajouter autant de champs que vous le souhaitez, par exemple.

  ...
  "script" : "ctx._source.category1 = \"10\"; ctx._source.category2 = \"20\";"

METTRE À JOUR

ES 2.3 propose désormais la fonctionnalité update by query . Vous pouvez toujours utiliser la requête ci-dessus telle quelle et cela fonctionnera (sauf que filtered et missing sont obsolètes, mais fonctionnent toujours;).

31
Val

Tout cela semble bien, mais pour ajouter à la réponse @Val, Update By Query est disponible sous ElasticSearch 2.x, mais pas pour les versions antérieures. Dans notre cas, nous utilisons la version 1.4 pour des raisons héritées et il n'y a aucune chance de mise à niveau dans un avenir prévisible. Une autre solution utilise donc le plug-in Mise à jour par requête fourni ici: https://github.com/yakaz/elasticsearch-action- updatebyquery

0
infinity