如何在MongoDB中同时从两个同结构集合获取指定数据?
Hey there! I see you need to pull combined results from two structurally identical collections (C1 and C2), apply your date filter, sort by the Date field in ascending order, and grab a total of 50 documents. Let's walk through the best ways to make this happen in MongoDB.
Method 1: Use $unionWith (MongoDB 4.4+)
This is the most efficient approach because $unionWith lets you merge results from multiple collections directly in the aggregation pipeline. You can apply sorting and limiting after merging, which is way better for performance—especially if your collections hold a lot of data.
Here's the query you can run in the Mongo Shell:
db.C1.aggregate([ // First filter C1 to match your date condition { $match: { "Date": { "$gt": ISODate("2018-05-18T00:00:00.203+0000") } } }, // Merge with filtered results from C2 { $unionWith: { coll: "C2", pipeline: [ { $match: { "Date": { "$gt": ISODate("2018-05-18T00:00:00.203+0000") } } } ] } }, // Sort all combined results by Date ascending { $sort: { "Date": 1 } }, // Keep only the first 50 documents { $limit: 50 } ])
Quick breakdown:
$match: Filters each collection to only include documents whereDateis newer than your specified ISO date (matches your original single-collection filter).$unionWith: Merges the filtered data from C1 and C2 into one unified result set.$sort: Orders the combined results byDatein ascending order (1= ascending,-1would be descending).$limit: Truncates the sorted list to just 50 documents, which is exactly what you need.
Method 2: Use $concatArrays (For Older MongoDB Versions)
If you're stuck on a MongoDB version before 4.4, you can use $concatArrays to combine results from two separate queries. Just a heads-up: this approach loads all matching documents from both collections into memory first, so it's less efficient for large datasets.
Here's how to implement it:
db.aggregate([ // Pull filtered documents from C1 { $lookup: { from: "C1", pipeline: [ { $match: { "Date": { "$gt": ISODate("2018-05-18T00:00:00.203+0000") } } } ], as: "c1_docs" } }, // Pull filtered documents from C2 { $lookup: { from: "C2", pipeline: [ { $match: { "Date": { "$gt": ISODate("2018-05-18T00:00:00.203+0000") } } } ], as: "c2_docs" } }, // Combine the two arrays into one { $project: { combined: { $concatArrays: ["$c1_docs", "$c2_docs"] } } }, // Unpack the combined array to work with individual documents { $unwind: "$combined" }, // Set each unwound document as the root of the result { $replaceRoot: { newRoot: "$combined" } }, // Sort by Date ascending { $sort: { "Date": 1 } }, // Limit to 50 documents { $limit: 50 } ])
Important note:
Avoid this method if your collections have thousands of matching documents—loading all that data into memory upfront can slow things down. Stick with $unionWith if you're on MongoDB 4.4 or newer.
内容的提问来源于stack exchange,提问作者Namrata Kamble

