能否使用IN操作符在Firestore数据库中检测数组是否被另一数组包含?
检测食材数组是否被库存数组完全包含的解决方案
给定数据:
ingredients1: ["banana","apple", "milk"]ingredients2: ["orange","apple", "water"]ingredients3: ["banana","kiwi", "milk"]inventory: ["banana","kiwi","milk","apple"]
要找出所有元素均被inventory包含的ingredients数组,可通过以下方式实现:
MongoDB 查询方案(适配查询构建器)
如果你的数据以单文档形式存储(包含上述所有字段),可以利用MongoDB的集合操作符$setIsSubset来判断数组子集关系:
1. 验证每个食材数组是否符合条件
使用聚合查询返回每个数组的验证结果:
db.collection.aggregate([ { $project: { ingredients1: { $setIsSubset: ["$ingredients1", "$inventory"] }, ingredients2: { $setIsSubset: ["$ingredients2", "$inventory"] }, ingredients3: { $setIsSubset: ["$ingredients3", "$inventory"] } } } ])
执行后会得到类似结果:
{ "_id": ObjectId("..."), "ingredients1": true, "ingredients2": false, "ingredients3": true }
其中true表示对应食材数组的所有元素都存在于库存中。
2. 直接返回符合条件的食材数组名称
如果需要直接提取符合条件的数组名称,可扩展聚合管道:
db.collection.aggregate([ { $project: { validIngredients: { $filter: { input: [ { name: "ingredients1", items: "$ingredients1" }, { name: "ingredients2", items: "$ingredients2" }, { name: "ingredients3", items: "$ingredients3" } ], cond: { $setIsSubset: ["$$this.items", "$inventory"] } } } } }, { $project: { validIngredientNames: "$validIngredients.name" } } ])
返回结果示例:
{ "_id": ObjectId("..."), "validIngredientNames": ["ingredients1", "ingredients3"] }
常见问题排查
你之前查询返回null,大概率是误用了操作符:
- 若使用
$all,它的作用是查询文档中某数组包含指定所有元素,而非判断数组是否为另一个数组的子集,方向完全相反; - 未正确使用集合类操作符(如
$setIsSubset),导致查询逻辑不匹配需求。
如果使用可视化查询构建器,需在投影阶段选择$setIsSubset操作符,分别指定食材数组和库存数组作为两个输入参数即可。
内容的提问来源于stack exchange,提问作者Alper Gökgöz
相关产品推荐
相关产品推荐

