Skip to content

Instantly share code, notes, and snippets.

@RienNeVaPlus
Last active August 7, 2019 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RienNeVaPlus/942cf74369037ad8f00e5d176ffe1773 to your computer and use it in GitHub Desktop.
Save RienNeVaPlus/942cf74369037ad8f00e5d176ffe1773 to your computer and use it in GitHub Desktop.
🥑 ArangoDB: Adds the much needed `collection.bulkUpsert` function to ArangoJS. Uses a single query instead of multiple expensive roundtrips.
import { Database, DocumentCollection } from 'arangojs'
const db = new Database(process.env.ARANGODB_URL);
db.useDatabase('name');
/**
* 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();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment