2016-11-03 1 views
2

J'étudie actuellement si ArangoDB peut être une alternative future pour nous. Dans le cadre de cette évaluation, je suis en train de porter du code qui parle à notre actuel NoSQL db en code qui parle ArangoDB. Bien que le trajet soit relativement fluide jusqu'à maintenant, j'ai du mal à comprendre comment mettre à jour les sous-documents. En supposant que nous avons quelque chose comme ceci:Mise à jour du sous-document ArangoDB

{ 
    "_key": "12345", 
    "subdoc": { 
     "0": { 
      "num_sold": 6, 
      "other_attribute": "important" 

    }, 
     "1": { 
      "num_sold": 4, 
      "other_attribute": "important" 
    } 
    } 
} 

Ce que je voudrais accomplir maintenant pour augmenter atomiquement num_sold.

Une première approche naïve était bien sûr d'essayer quelque chose de similaire à:

FOR d in @@collection 
    FILTER d._key == "12345" 
    UPDATE d WITH { subdoc.0.num_sold : subdoc.0.num_sold + 1 } IN @@collection 
RETURN d 

(alerte Spoiler pour la copie-dérouleurs là-bas.. Passer Cet extrait sera tout simplement rendre votre vie misérable)

Cela n'a évidemment pas fonctionné et probablement pour plus d'une raison. Arango ne semble pas aimer me référencer l'attribut en utilisant la notation par points, l'attribut commençant par un nombre ("0") pourrait également être un problème etc. Tout en ayant trouvé un exemple here il semblait à la fois un peu compliqué et compliqué pour ce que je suis essayer de faire. Il y a aussi une autre discussion here qui est proche de ce que je voudrais faire. Cependant, la solution proposée dans cette discussion utilise le mot-clé OLD qui crée une erreur dans mon cas ainsi que le code remplaçant toutes les clés dans "0".

1) Quelle est la meilleure façon d'augmenter de façon atomique num_sold?

2) Quand une opération est-elle atomique? (Essayer de rester à l'écart des transactions le plus longtemps possible)

3) Quand la notation par points peut-elle être utilisée et quand ne peut-elle pas être utilisée?

4) Puis-je lier des paramètres à un attribut? Par exemple laisser @attribute être subdoc.0.num_sold?

Merci!

Répondre

1

ArangoDB ne peut pas analyser la requête si vous utilisez des nombres dans la notation par points. Cependant, il existe un moyen facile - utilisez simplement des crochets au lieu de la notation par points comme vous l'avez fait.

Exemple - ne fonctionne pas:

db._query(` 
    LET testdoc = {subdoc: {"0": "abc"}} 
    RETURN testdoc.subdoc.0`) 

ArangoError 1501: syntax error, unexpected integer number, 
expecting identifier or bind parameter near '0' at 
position 1:60 (while parsing) 

Exemple - fixe:

db._query(` 
    LET testdoc = {subdoc: {"0": "abc"}} 
    RETURN testdoc.subdoc.[0]`) 

[ 
    "abc" 
] 

En utilisant les variables de liaison - ne fonctionne pas:

db._query(` 
    LET testdoc = {subdoc: {"0": "abc"}} 
    RETURN [email protected]`, {bv: 0}) 

ArangoError 1501: syntax error, unexpected integer number, 
expecting identifier or bind parameter near '0' at 
position 1:60 (while parsing) 

En utilisant les variables de liaison - fixe:

db._query(` 
    LET testdoc = {subdoc: {"0": "abc"}} 
    RETURN testdoc.subdoc.[@bv]`, {bv:0}) 

[ 
    "abc" 
]