如何查询数组字段包含给定数组全部元素的MongoDB文档?
你要实现的是数组字段包含所有指定元素的查询需求,不同场景的实现方式如下:
MongoDB 原生实现
你示例里用到的$all本身就是MongoDB原生支持的查询运算符,直接使用即可完全匹配你需要的效果,注意如果要返回所有符合条件的文档请用find方法,findOne只会返回第一条匹配结果:
- 查询同时包含
a和b的文档:
db.collection.find({ tags: { $all: ["a", "b"] } }) // 返回id为1的文档
- 查询包含
b的文档:
db.collection.find({ tags: { $all: ["b"] } }) // 返回id为1、2的文档
- 查询同时包含
a、b、d的文档:
db.collection.find({ tags: { $all: ["a", "b", "d"] } }) // 无匹配结果返回空
- 查询包含
d的文档:
db.collection.find({ tags: { $all: ["d"] } }) // 返回id为3的文档
MySQL 实现
如果是MySQL存储场景,分两种情况处理:
存储为JSON数组字段
用JSON_CONTAINS函数组合条件即可:
-- 同时包含a和b的查询示例 SELECT * FROM 表名 WHERE JSON_CONTAINS(tags, '"a"') AND JSON_CONTAINS(tags, '"b"');
用关联表存储标签(文档id和tag一对一关联)
用分组加HAVING实现:
-- 同时包含a和b的查询示例,HAVING后的数字对应要匹配的标签数量 SELECT 文档id FROM tags关联表 WHERE tag IN ('a', 'b') GROUP BY 文档id HAVING COUNT(DISTINCT tag) = 2;
内存数组过滤实现(JS/Node.js场景)
如果是直接在内存里过滤本地数组,用数组的every方法实现即可:
const filterByAllTags = (docList, targetTags) => { return docList.filter(doc => targetTags.every(tag => doc.tags.includes(tag)) ) } // 调用示例:filterByAllTags(你的文档数组, ['a','b']) 即可返回符合条件的所有文档
内容的提问来源于stack exchange,提问作者Tlaloc-ES
相关产品推荐
相关产品推荐

