我发现如果密钥不存在,我可以.save(objects)
创建对象。我发现我可以.bulkUpdate(objects)
来更新存在其键的对象。
我的问题是:如何进行批量增补?如果该密钥存在,则对其进行更新(合并),如果不存在,则对其进行创建。
有没有办法做到这一点而又没有很多开销?
这样做可以接受吗?
db.collection("threads").bulkUpdate(keyedThreads);
db.collection("threads").save(keyedThreads);
答案 0 :(得分:0)
REST插入具有覆盖选项。那可能就是您想要的。
https://github.com/arangodb/arangojs/blob/master/src/collection.ts#L721
如果不是,则需要使用AQL UPSERT。
答案 1 :(得分:0)
@pluma(ArangoDB)wrote于2017年6月9日:
Upsert仅可通过AQL使用。没有collection.upsert方法。
并添加了@fceller(ArangoDB):
upsert的主要问题之一是您访问旧数据。这可以在AQL中轻松处理,但不能通过简单调用upsert端点来解决。因此,我们决定不进行此类呼叫,而是在AQL中实施了该呼叫。
好像永远不会有collection.bulkUpsert
的本地实现;但是,您可以使用AQL的UPSERT和MERGE函数来创建自己的帮助函数。
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();
}