【问题标题】:Bulk upsert in ArangoJS?在 ArangoJS 中批量插入?
【发布时间】:2019-02-01 15:00:47
【问题描述】:

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

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

有没有办法做到这一点而无需大量开销?

这样做可以接受吗?

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

【问题讨论】:

    标签: arangodb arangojs


    【解决方案1】:

    @pluma (ArangoDB) wrote 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 Gist

    【讨论】:

      【解决方案2】:

      REST 插入具有覆盖选项。这可能就是您正在寻找的。​​p>

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

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

      【讨论】:

      • 如果我错了,请纠正我,但这不会替换文档而不是合并它们吗?
      • @LukePighetti 你是对的。如果您不只是想将数据从应用程序同步到数据库,则需要编写一个使用 UPSERT 语句的 AQL 查询。没有 upsert REST / 文档处理程序。
      猜你喜欢
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-15
      • 1970-01-01
      相关资源
      最近更新 更多