[英]How to Perform UPSERT Operation in Arango DB with Different multiple keys (Composite Key)?
In official documentations, it's already shown how to do that.在官方文档中,它已经展示了如何做到这一点。 Below, an example that working fine:下面是一个工作正常的例子:
Example: 1示例:1
LET documents = [
{ name: 'Doc 1', value: 111, description: 'description 111' },
{ name: 'Doc 2', value: 222, description: 'description 2' },
{ name: 'Doc 3', value: 333, description: 'description 3' }
]
FOR doc IN documents
UPSERT { name: doc.name, description: doc.description }
INSERT doc
UPDATE doc
IN MyCollection
But, I want to check different multiple keys for each document on UPSERT, like:但是,我想为 UPSERT 上的每个文档检查不同的多个键,例如:
Example: 2示例:2
LET documents = [
{ name: 'Doc 1', value: 777, description: 'description 111' },
{ name: 'Doc 2', value: 888, description: 'description 2' },
{ name: 'Doc 3', value: 999, description: 'description 3' }
]
FOR doc IN documents
UPSERT {
{ name: doc.name, description: doc.description },
{ value: doc.value, description: doc.description },
{ name: doc.name, value: doc.value }
}
INSERT doc
UPDATE doc
IN MyCollection
Or, any other other way (using filter or something).或者,任何其他方式(使用过滤器或其他东西)。 I had tried but nothing works我试过了,但没有任何效果
If I understand your problem, you would want to update a document, if there's an existing one with at least 2 fields matching, otherwise insert it as new.如果我理解你的问题,你会想要更新一个文档,如果有一个至少有 2 个字段匹配的现有文档,否则将它作为新的插入。
UPSERT won't be able to do that. UPSERT 将无法做到这一点。 It can only do one match.它只能进行一场比赛。 So a subquery is necessary.所以子查询是必要的。 In the solution below, I ran a query to find the key of the first document that matches at least 2 fields.在下面的解决方案中,我运行了一个查询来查找与至少 2 个字段匹配的第一个文档的键。 If there's no such document then it will return null
.如果没有这样的文件,那么它将返回null
。
Then the UPSERT can work by matching the _key
to that.然后 UPSERT 可以通过将_key
匹配来工作。
LET documents = [
{ name: 'Doc 1', value: 777, description: 'description 111' },
{ name: 'Doc 2', value: 888, description: 'description 2' },
{ name: 'Doc 3', value: 999, description: 'description 3' }
]
FOR doc IN documents
LET matchKey= FIRST(
FOR rec IN MyCollection
FILTER (rec.name==doc.name) + (rec.value==doc.value) + (rec.description==doc.description) > 1
LIMIT 1
RETURN rec._key
)
UPSERT {_key:matchKey}
INSERT doc
UPDATE doc
IN MyCollection
Note: There's a trick with adding booleans together which works because true will be converted to 1, while false is zero.注意:将布尔值加在一起有一个技巧,因为 true 将转换为 1,而 false 为零。 You can write it out explicitly like this: (rec.name==doc.name?1:0)
你可以像这样明确地写出来: (rec.name==doc.name?1:0)
While this will work for you it's not a very effective solution.虽然这对您有用,但这不是一个非常有效的解决方案。 Actually there's no effective one in this case because all the existing documents need to be scoured through to find a matching one, for each document to be added/updated.实际上在这种情况下没有有效的文档,因为需要搜索所有现有文档以找到匹配的文档,以添加/更新每个文档。 I'm not sure what kind of problem you are trying to solve with this, but it might be better to re-think your design so that the matching condition could be more simple.我不确定你想用这个解决什么样的问题,但重新考虑你的设计可能会更好,这样匹配条件就可以更简单。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.