我目前正在评估ArangoDB是否可以成为我们未来的替代方案。作为评估的一部分,我将代码与我们当前的NoSQL数据库移植到代表ArangoDB的代码中。虽然到目前为止一直是一个相当平稳的旅程,但我很难绕过如何更新子文档。假设我们有类似的东西:
{
"_key": "12345",
"subdoc": {
"0": {
"num_sold": 6,
"other_attribute": "important"
},
"1": {
"num_sold": 4,
"other_attribute": "important"
}
}
}
我想要实现的目标是以原子方式增加num_sold
。
第一个天真的方法当然是尝试类似的东西:
FOR d in @@collection
FILTER d._key == "12345"
UPDATE d WITH { subdoc.0.num_sold : subdoc.0.num_sold + 1 } IN @@collection
RETURN d
(Spoiler提醒那里的复制贴纸:继续前进。这个片段只会让你的生活变得悲惨。)
这显然不起作用,而且很可能不止一个原因。 Arango似乎不喜欢我使用点表示法引用属性,以数字开头的属性(" 0")也可能是一个问题等。虽然找到了一个例子here但它似乎都是我想要做的事情有点复杂和复杂。还有另一个讨论here接近我想做的事情。但是,该讨论中提出的解决方案使用了在我的情况下创建错误的关键字OLD
以及替换" 0"中的所有键的代码。
1)以原子方式增加num_sold
的最佳方式是什么?
2)什么是原子操作? (试图尽可能远离交易)
3)何时可以使用点符号以及什么时候不能使用?
4)我可以将参数绑定到属性吗?例如,让某些@attribute
为subdoc.0.num_sold
?
谢谢!
答案 0 :(得分:2)
如果您使用点表示法中的数字,ArangoDB无法解析查询。 然而,有一种简单的方法 - 只需使用括号而不是点符号。
示例 - 不工作:
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)
示例 - 已修复:
db._query(`
LET testdoc = {subdoc: {"0": "abc"}}
RETURN testdoc.subdoc.[0]`)
[
"abc"
]
使用绑定变量 - 不工作:
db._query(`
LET testdoc = {subdoc: {"0": "abc"}}
RETURN testdoc.subdoc.@bv`, {bv: 0})
ArangoError 1501: syntax error, unexpected integer number,
expecting identifier or bind parameter near '0' at
position 1:60 (while parsing)
使用绑定变量 - 已修复:
db._query(`
LET testdoc = {subdoc: {"0": "abc"}}
RETURN testdoc.subdoc.[@bv]`, {bv:0})
[
"abc"
]