联合 2 个表,就像它是单个实体一样,然后排序、跳过和限制 (Mongoose)
Union 2 tables like it is a single entity, then sort, skip, and limit (Mongoose)
我有 2 个模式,模式 A 和 B,如下所示:
const A = new Schema({
paymentId: Number,
date: Date,
...data
})
const B = new Schema({
paidId: Number,
date: Date,
...data
})
我想 return 来自 A 和 B 的记录,就像它是单个 table,我可以从 A 和 B 中获取可与 .sort()
一起使用的记录、.skip()
和 .limit()
功能理想。
我可以在两个 table 上做一个 .find()
,连接它们,然后手动排序/跳过/限制,但我发现效率非常低。
编辑:澄清一下。这两个集合是否相关并不重要。我只想从两个集合中查询,就像它们都在一个集合中一样。
例如,如果我有以下文件
// Documents in A
{ date: '2020-01-01', A_id: 1 },
{ date: '2020-01-03', A_id: 2 },
{ date: '2020-01-05', A_id: 3 },
// Documents in B
{ date: '2020-01-02', B_id: 1 },
{ date: '2020-01-04', B_id: 2 },
{ date: '2020-01-06', B_id: 3 },
使用选项 .sort('date').skip(0).limit(5)
进行查询应该得到以下结果:
// Documents in A and B
{ date: '2020-01-01', A_id: 1 },
{ date: '2020-01-02', B_id: 1 },
{ date: '2020-01-03', A_id: 2 },
{ date: '2020-01-04', B_id: 2 },
{ date: '2020-01-05', A_id: 3 },
//Can I suggest, $merge to merge these two independent collections into another different collection
//and then use aggregation to doing sort(),skip() and limit()
> db.version();
4.2.6
> db.colA.find();
{ "_id" : ObjectId("5f76d969975ec8826bbcaab5"), "date" : "2020-01-01", "A_id" : 1 }
{ "_id" : ObjectId("5f76d969975ec8826bbcaab6"), "date" : "2020-01-03", "A_id" : 2 }
{ "_id" : ObjectId("5f76d969975ec8826bbcaab7"), "date" : "2020-01-05", "A_id" : 3 }
> db.colB.find();
{ "_id" : ObjectId("5f76d969975ec8826bbcaab8"), "date" : "2020-01-02", "B_id" : 1 }
{ "_id" : ObjectId("5f76d969975ec8826bbcaab9"), "date" : "2020-01-04", "B_id" : 2 }
{ "_id" : ObjectId("5f76d969975ec8826bbcaaba"), "date" : "2020-01-06", "B_id" : 3 }
> db.colA.aggregate([
{$match:{}},
{$merge:{into: "colAB"}}
]);
>db.colB.aggregate([
{$match:{}},
{$merge:{into: "colAB"}}
]);
> db.colAB.find();
{ "_id" : ObjectId("5f76d969975ec8826bbcaab5"), "A_id" : 1, "date" : "2020-01-01" }
{ "_id" : ObjectId("5f76d969975ec8826bbcaab6"), "A_id" : 2, "date" : "2020-01-03" }
{ "_id" : ObjectId("5f76d969975ec8826bbcaab7"), "A_id" : 3, "date" : "2020-01-05" }
{ "_id" : ObjectId("5f76d969975ec8826bbcaab8"), "B_id" : 1, "date" : "2020-01-02" }
{ "_id" : ObjectId("5f76d969975ec8826bbcaab9"), "B_id" : 2, "date" : "2020-01-04" }
{ "_id" : ObjectId("5f76d969975ec8826bbcaaba"), "B_id" : 3, "date" : "2020-01-06" }
> > db.colAB.aggregate([
... {$project:{_id:0}},
... {$sort:{date:1}},
... {$skip:0},
... {$limit:5}
... ]);
{ "A_id" : 1, "date" : "2020-01-01" }
{ "B_id" : 1, "date" : "2020-01-02" }
{ "A_id" : 2, "date" : "2020-01-03" }
{ "B_id" : 2, "date" : "2020-01-04" }
{ "A_id" : 3, "date" : "2020-01-05" }
来自:
Doing unions in MongoDB in a 'SQL UNION' fashion is possible using
aggregations along with lookups, in a single query.
Something like this:
db.getCollection("AnyCollectionThatContainsAtLeastOneDocument").aggregate(
[
{ $limit: 1 }, // Reduce the result set to a single document.
{ $project: { _id: 1 } }, // Strip all fields except the Id.
{ $project: { _id: 0 } }, // Strip the id. The document is now empty.
// Lookup all collections to union together.
{ $lookup: { from: 'collectionToUnion1', pipeline: [...], as: 'Collection1' } },
{ $lookup: { from: 'collectionToUnion2', pipeline: [...], as: 'Collection2' } },
{ $lookup: { from: 'collectionToUnion3', pipeline: [...], as: 'Collection3' } },
// Merge the collections together.
{
$project:
{
Union: { $concatArrays: ["$Collection1", "$Collection2", "$Collection3"] }
}
},
{ $unwind: "$Union" }, // Unwind the union collection into a result set.
{ $replaceRoot: { newRoot: "$Union" } } // Replace the root to cleanup the resulting documents.
]);
更多详细信息在上面的 post 中。添加 $sort
、$skip
和 $limit
只是将它们添加到聚合管道的问题。非常感谢@sboisse!
我有 2 个模式,模式 A 和 B,如下所示:
const A = new Schema({
paymentId: Number,
date: Date,
...data
})
const B = new Schema({
paidId: Number,
date: Date,
...data
})
我想 return 来自 A 和 B 的记录,就像它是单个 table,我可以从 A 和 B 中获取可与 .sort()
一起使用的记录、.skip()
和 .limit()
功能理想。
我可以在两个 table 上做一个 .find()
,连接它们,然后手动排序/跳过/限制,但我发现效率非常低。
编辑:澄清一下。这两个集合是否相关并不重要。我只想从两个集合中查询,就像它们都在一个集合中一样。
例如,如果我有以下文件
// Documents in A
{ date: '2020-01-01', A_id: 1 },
{ date: '2020-01-03', A_id: 2 },
{ date: '2020-01-05', A_id: 3 },
// Documents in B
{ date: '2020-01-02', B_id: 1 },
{ date: '2020-01-04', B_id: 2 },
{ date: '2020-01-06', B_id: 3 },
使用选项 .sort('date').skip(0).limit(5)
进行查询应该得到以下结果:
// Documents in A and B
{ date: '2020-01-01', A_id: 1 },
{ date: '2020-01-02', B_id: 1 },
{ date: '2020-01-03', A_id: 2 },
{ date: '2020-01-04', B_id: 2 },
{ date: '2020-01-05', A_id: 3 },
//Can I suggest, $merge to merge these two independent collections into another different collection
//and then use aggregation to doing sort(),skip() and limit()
> db.version();
4.2.6
> db.colA.find();
{ "_id" : ObjectId("5f76d969975ec8826bbcaab5"), "date" : "2020-01-01", "A_id" : 1 }
{ "_id" : ObjectId("5f76d969975ec8826bbcaab6"), "date" : "2020-01-03", "A_id" : 2 }
{ "_id" : ObjectId("5f76d969975ec8826bbcaab7"), "date" : "2020-01-05", "A_id" : 3 }
> db.colB.find();
{ "_id" : ObjectId("5f76d969975ec8826bbcaab8"), "date" : "2020-01-02", "B_id" : 1 }
{ "_id" : ObjectId("5f76d969975ec8826bbcaab9"), "date" : "2020-01-04", "B_id" : 2 }
{ "_id" : ObjectId("5f76d969975ec8826bbcaaba"), "date" : "2020-01-06", "B_id" : 3 }
> db.colA.aggregate([
{$match:{}},
{$merge:{into: "colAB"}}
]);
>db.colB.aggregate([
{$match:{}},
{$merge:{into: "colAB"}}
]);
> db.colAB.find();
{ "_id" : ObjectId("5f76d969975ec8826bbcaab5"), "A_id" : 1, "date" : "2020-01-01" }
{ "_id" : ObjectId("5f76d969975ec8826bbcaab6"), "A_id" : 2, "date" : "2020-01-03" }
{ "_id" : ObjectId("5f76d969975ec8826bbcaab7"), "A_id" : 3, "date" : "2020-01-05" }
{ "_id" : ObjectId("5f76d969975ec8826bbcaab8"), "B_id" : 1, "date" : "2020-01-02" }
{ "_id" : ObjectId("5f76d969975ec8826bbcaab9"), "B_id" : 2, "date" : "2020-01-04" }
{ "_id" : ObjectId("5f76d969975ec8826bbcaaba"), "B_id" : 3, "date" : "2020-01-06" }
> > db.colAB.aggregate([
... {$project:{_id:0}},
... {$sort:{date:1}},
... {$skip:0},
... {$limit:5}
... ]);
{ "A_id" : 1, "date" : "2020-01-01" }
{ "B_id" : 1, "date" : "2020-01-02" }
{ "A_id" : 2, "date" : "2020-01-03" }
{ "B_id" : 2, "date" : "2020-01-04" }
{ "A_id" : 3, "date" : "2020-01-05" }
来自
Doing unions in MongoDB in a 'SQL UNION' fashion is possible using aggregations along with lookups, in a single query.
Something like this:
db.getCollection("AnyCollectionThatContainsAtLeastOneDocument").aggregate( [ { $limit: 1 }, // Reduce the result set to a single document. { $project: { _id: 1 } }, // Strip all fields except the Id. { $project: { _id: 0 } }, // Strip the id. The document is now empty. // Lookup all collections to union together. { $lookup: { from: 'collectionToUnion1', pipeline: [...], as: 'Collection1' } }, { $lookup: { from: 'collectionToUnion2', pipeline: [...], as: 'Collection2' } }, { $lookup: { from: 'collectionToUnion3', pipeline: [...], as: 'Collection3' } }, // Merge the collections together. { $project: { Union: { $concatArrays: ["$Collection1", "$Collection2", "$Collection3"] } } }, { $unwind: "$Union" }, // Unwind the union collection into a result set. { $replaceRoot: { newRoot: "$Union" } } // Replace the root to cleanup the resulting documents. ]);
更多详细信息在上面的 post 中。添加 $sort
、$skip
和 $limit
只是将它们添加到聚合管道的问题。非常感谢@sboisse!