Skip to content

Instantly share code, notes, and snippets.

@alethes
Last active January 3, 2020 11:38
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 alethes/369faf2e1c5a83f4fbcaca9001dbd501 to your computer and use it in GitHub Desktop.
Save alethes/369faf2e1c5a83f4fbcaca9001dbd501 to your computer and use it in GitHub Desktop.
const N = 1000;
db.items.remove({});
db.users.remove({});
db.items.createIndex({ features: 1, owner: 1 });
db.users.createIndex({ items: 1 });
db.users.createIndex({ partner: 1 });
for (let i = 0; i < N; i++) {
const user = i; // ObjectId();
const item = i; // ObjectId();
db.items.insert({ _id: item, size: Math.random(), owner: user });
db.users.insert({ _id: user, items: [item], partner: N - user - 1 });
}
print("\nMatch + 2 lookups");
let before = new Date();
let r = db.items
.aggregate([
{
$match: { size: { $lt: 0.5 } }
},
{
$lookup: {
as: "owner",
from: "users",
let: { id: "$_id" },
pipeline: [
{ $match: { $expr: { $in: ["$$id", "$items"] } } },
{
$lookup: {
as: "partner",
from: "users",
let: { id: "$_id" },
pipeline: [{ $match: { $expr: { $eq: ["$$id", "$partner"] } } }]
}
},
{ $project: { partner: { $arrayElemAt: ["$partner", 0] } } }
]
}
},
{ $project: { size: 1, owner: { $arrayElemAt: ["$owner", 0] } } }
])
.toArray();
// printjson(r[0]);
// printjson(r.length);
print("Aggregation 1:", new Date() - before, "ms");
before = new Date();
r = db.items
.aggregate([
{
$match: { size: { $lt: 0.5 } }
},
{
$lookup: {
as: "owner",
from: "users",
let: { owner: "$owner" },
pipeline: [
{ $match: { $expr: { $eq: ["$_id", "$$owner"] } } },
{
$lookup: {
as: "partner",
from: "users",
let: { partner: "$partner" },
pipeline: [{ $match: { $expr: { $eq: ["$_id", "$$partner"] } } }]
}
},
{ $project: { partner: { $arrayElemAt: ["$partner", 0] } } }
]
}
},
{ $project: { size: 1, owner: { $arrayElemAt: ["$owner", 0] } } }
])
.toArray();
// printjson(r[0]);
// printjson(r.length);
print("Aggregation 2:", new Date() - before, "ms");
before = new Date();
r = db.items
.aggregate([
{
$match: { size: { $lt: 0.5 } }
},
{
$lookup: {
from: "users",
localField: "_id",
foreignField: "items",
as: "owner"
}
},
{ $unwind: "$owner" },
{ $project: { "owner.items": 0 } },
{
$lookup: {
from: "users",
localField: "owner.partner",
foreignField: "_id",
as: "owner.partner"
}
},
{ $unwind: "$owner.partner" }
])
.toArray();
// printjson(r[0]);
// printjson(r.length);
print("Aggregation 3:", new Date() - before, "ms");
const find = (col, q) => col.find(q).toArray();
const byId = arr =>
arr.reduce((a, b) => {
a[b._id] = b;
return a;
}, {});
const fieldVals = (arr, field) => arr.map(a => a[field]);
before = new Date();
const items = find(db.items, { size: { $lt: 0.5 } });
const itemsById = byId(items);
const itemIds = fieldVals(items, "_id");
const users = find(db.users, { items: { $in: itemIds } });
const partnerIds = fieldVals(users, "partner");
const partners = find(db.users, { _id: { $in: partnerIds } });
const partnersById = byId(partners);
users.forEach(u => {
u.items.forEach(i => {
itemsById[i].owner = u;
});
u.partner = partnersById[u.partner];
delete u.items;
});
// printjson(items[0]);
// printjson(items.length);
print("Find:", new Date() - before, "ms");
before = new Date();
print("\nMatch only");
r = db.items
.aggregate([
{
$match: { size: { $lt: 0.5 } }
}
])
.toArray();
print("Match:", new Date() - before, "ms");
before = new Date();
r = db.items
.find({
size: { $lt: 0.5 }
})
.toArray();
print("Find:", new Date() - before, "ms");
before = new Date();
print("\nMatch + lookup");
r = db.items
.aggregate([
{
$match: { size: { $lt: 0.5 } }
},
{
$lookup: {
from: "users",
localField: "_id",
foreignField: "items",
as: "owner"
}
}
])
.toArray();
print("Match:", new Date() - before, "ms");
before = new Date();
{
const items = find(db.items, { size: { $lt: 0.5 } });
const itemsById = byId(items);
const itemIds = fieldVals(items, "_id");
const users = find(db.users, { items: { $in: itemIds } });
users.forEach(u => {
u.items.forEach(i => {
itemsById[i].owner = u;
});
delete u.items;
});
}
print("Find:", new Date() - before, "ms");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment