2

我发现.save(objects)如果密钥不存在,我可以创建对象。我发现我可以.bulkUpdate(objects)更新其键存在的对象。

我的问题是:如何进行批量更新?如果密钥存在,则更新它(合并),如果不存在,则创建它。

有没有办法在没有大量开销的情况下做到这一点?

这样做可以接受吗?

db.collection("threads").bulkUpdate(keyedThreads);
db.collection("threads").save(keyedThreads);
4

2 回答 2

2

@pluma (ArangoDB)在 2017 年 6 月 9 日写道:

Upsert 只能通过 AQL 获得。没有 collection.upsert 方法。

@fceller ( ArangoDB ) 补充道:

upsert 的主要问题之一是您访问旧数据。这可以在 AQL 中轻松处理,但不能通过对 upsert 端点的简单调用来处理。因此,我们决定反对这样的调用,而是在 AQL 中实现它。

看起来永远不会有 ; 的本机实现collection.bulkUpsert但是,您可以使用 AQL 的UPSERTMERGE函数创建自己的辅助函数。

TypeScript例子:

/**
 * Upserts (merges) the content of the documents with the given documents and
 * optionally returns an array containing the documents’ metadata.
 *
 * @param {string|ArangoDB.Collection} collection - collection to use
 * @param {Document[]} documents - list of documents to upsert
 * @param opts? - optionally aggregate a result {inserted:number,updated:number}
 *  also see https://www.arangodb.com/docs/stable/aql/operations-upsert.html
 */
export async function bulkUpsert(
    collection: string | DocumentCollection,
    documents: Array<ArangoDB.DocumentData>,
    { aggregate, ...upsertOptions }: {
        ignoreRevs?: boolean,
        exclusive?: boolean,
        aggregate?: boolean
    } = {}
): Promise<{inserted:number,updated:number} | true>
{
    return await (
        await db.query({
            query:  'FOR doc IN @documents'
                  + ' UPSERT { _key: doc._key } INSERT doc UPDATE MERGE(OLD, doc)'
                  + ' IN '+(typeof collection === 'string' ? collection : collection.name)
                  + ' OPTIONS '+JSON.stringify(upsertOptions)
                  + (aggregate ?
                    ' COLLECT AGGREGATE inserted = SUM(OLD ? 0 : 1), updated = SUM(OLD ? 1 : 0)'
                  + ' RETURN {inserted,updated}' :
                    ' RETURN true'),
            bindVars: {documents}
        })
    ).next();
}

来源:collection.bulkUpsert.ts 要点

于 2019-11-03T08:42:27.877 回答
1

REST Insert 具有覆盖选项。这可能就是您正在寻找的。

https://github.com/arangodb/arangojs/blob/master/src/collection.ts#L721

如果不是,您需要使用 AQL UPSERT。

于 2019-02-01T17:32:07.117 回答