Mongoose查询:找出数组字段完全包含于指定数组的所有文档
Hey there! I get exactly what you're trying to do here — you want to pull all recipes from your Recipe collection where every ingredient in the ingredients array is part of your target list (['banana', 'apple', 'orange', 'mango']), right? That means excluding any recipe that has an ingredient outside that list (like the kiwi in your third test document).
The Cleanest Solution (MongoDB 3.2+)
Starting with MongoDB 3.2, you can use the $setIsSubset aggregation operator wrapped in $expr to make this query super straightforward. Here's the code:
db.Recipe.find({ $expr: { $setIsSubset: ["$ingredients", ["banana", "apple", "orange", "mango"]] } })
How this works:
$setIsSubsetchecks if the first array (the document'singredientsfield) is a full subset of the second array (your target ingredient list). In plain terms: every item in the recipe's ingredients has to exist in your allowed list.$exprlets you use aggregation expressions directly in a query filter, which is necessary here since$setIsSubsetis an aggregation operator.
Testing this against your sample data:
- Document 1 (
['banana', 'apple']): All ingredients are in the target list → returned - Document 2 (
['banana', 'apple', 'orange']): Same deal, all ingredients are allowed → returned - Document 3 (
['apple', 'orange', 'kiwi']): Kiwi isn't in your target list → excluded
Perfect match for what you need!
For Older MongoDB Versions (Pre-3.2)
If you're stuck on an older version where $expr isn't available, you can use a combination of $not and $elemMatch to get the same result:
db.Recipe.find({ ingredients: { $not: { $elemMatch: { $nin: ["banana", "apple", "orange", "mango"] } } } })
This logic flips the problem on its head: it finds recipes where no ingredient in the ingredients array is not in your target list. Which is exactly the same as saying all ingredients are in the list.
内容的提问来源于stack exchange,提问作者Gusti

