简体   繁体   English

如何在Arango DB中使用不同的多键(复合键)执行UPSERT操作?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM