Skip to content

Commit 67d2099

Browse files
bewestCopilot
andcommitted
perf: optimize activity and food storage with bulkWrite
Replace sequential replaceOne calls with bulkWrite for batch upserts. This improves performance when inserting multiple documents at once. - activity.js: Use bulkWrite with replaceOne ops instead of forEach loop - food.js: Same optimization for consistency Both maintain exact same upsert behavior (query by _id+created_at or doc). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent ef7bff3 commit 67d2099

2 files changed

Lines changed: 56 additions & 22 deletions

File tree

lib/server/activity.js

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,39 @@ function storage (env, ctx) {
77
var ObjectID = require('mongodb-legacy').ObjectId;
88

99
function create (docs, fn) {
10-
var firstErr = null
11-
, numDocs = docs.length
12-
, totalCreated = 0;
10+
if (docs.length === 0) {
11+
return fn(null, []);
12+
}
1313

14-
docs.forEach(function(doc) {
14+
// Build bulkWrite operations for batch upsert
15+
var bulkOps = docs.map(function(doc) {
1516
if (!Object.prototype.hasOwnProperty.call(doc, 'created_at')) {
16-
doc.created_at = (new Date( )).toISOString( );
17+
doc.created_at = (new Date()).toISOString();
1718
}
1819
var query = (doc.created_at && doc._id) ? { _id: doc._id, created_at: doc.created_at } : doc;
19-
api().replaceOne(query, doc, { upsert: true }, function(err, updateResults) {
20-
firstErr = firstErr || err;
21-
22-
if (++totalCreated === numDocs) {
23-
fn(firstErr, docs);
20+
return {
21+
replaceOne: {
22+
filter: query,
23+
replacement: doc,
24+
upsert: true
2425
}
25-
});
26+
};
27+
});
28+
29+
api().bulkWrite(bulkOps, { ordered: true }, function(err, bulkResult) {
30+
if (err) {
31+
console.error('Problem upserting activity batch', err);
32+
return fn(err, []);
33+
}
34+
35+
// Assign _ids from upserted results
36+
if (bulkResult && bulkResult.upsertedIds) {
37+
Object.keys(bulkResult.upsertedIds).forEach(function(index) {
38+
docs[index]._id = bulkResult.upsertedIds[index];
39+
});
40+
}
41+
42+
fn(null, docs);
2643
});
2744
}
2845

lib/server/food.js

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,37 @@ function storage (env, ctx) {
99
docs = [docs];
1010
}
1111

12-
var firstErr = null
13-
, numDocs = docs.length
14-
, totalCreated = 0;
12+
if (docs.length === 0) {
13+
return fn(null, []);
14+
}
1515

16-
docs.forEach(function(doc) {
17-
doc.created_at = (new Date( )).toISOString( );
16+
// Build bulkWrite operations for batch upsert
17+
var bulkOps = docs.map(function(doc) {
18+
doc.created_at = (new Date()).toISOString();
1819
var query = (doc.created_at && doc._id) ? { _id: doc._id, created_at: doc.created_at } : doc;
19-
api().replaceOne(query, doc, { upsert: true }, function(err, updateResults) {
20-
firstErr = firstErr || err;
21-
22-
if (++totalCreated === numDocs) {
23-
fn(firstErr, docs);
20+
return {
21+
replaceOne: {
22+
filter: query,
23+
replacement: doc,
24+
upsert: true
2425
}
25-
});
26+
};
27+
});
28+
29+
api().bulkWrite(bulkOps, { ordered: true }, function(err, bulkResult) {
30+
if (err) {
31+
console.error('Problem upserting food batch', err);
32+
return fn(err, []);
33+
}
34+
35+
// Assign _ids from upserted results
36+
if (bulkResult && bulkResult.upsertedIds) {
37+
Object.keys(bulkResult.upsertedIds).forEach(function(index) {
38+
docs[index]._id = bulkResult.upsertedIds[index];
39+
});
40+
}
41+
42+
fn(null, docs);
2643
});
2744
}
2845

0 commit comments

Comments
 (0)