如何将键值对推入数组构建MongoDB动态查询并拆分$in数组条件
核心问题定位
原代码无法生成预期查询结构,主要存在3处逻辑错误:
- 类型判断逻辑完全失效:
if(typeof(payload[key]))写法永远为真,因为typeof对非undefined的值会返回非空的类型字符串(如"number"、"string"),属于truthy值,导致永远无法触发else分支的特殊处理逻辑。 - 数组类型字段未做适配:遇到数组类字段(如示例中的
values),代码直接将原数组整体作为字段值推入查询条件,既没有按照MongoDB语法构造$in查询结构,也没有将数组内的复合对象拆分为单键匹配元素。 - 特殊分支的查询结构错误:即使进入else分支,原代码将
$in放在条件对象的顶层,写法完全不符合MongoDB查询规范,正确结构应为{ 字段名: { "$in": 匹配值列表 } }。
调整方案
遍历payload的键值对时按值的类型做分支处理:
- 字段值为非数组类型时,直接将键值对作为普通查询条件推入结果数组。
- 字段值为数组类型时,先将数组内的复合对象拆分为单键组成的匹配列表,再构造标准的
$in查询结构推入结果数组。
调整后可运行代码
const queryFormat = (payload) => { // 浅拷贝避免直接修改传入的原对象 const targetPayload = { ...payload } delete targetPayload.userEventId const query = {} const res = [] for (const key in targetPayload) { const value = targetPayload[key] if (Array.isArray(value)) { // 拆解数组内的复合对象为单键匹配项 const inMatchList = value.flatMap(item => Object.entries(item).map(([k, v]) => ({ [k]: v })) ) res.push({ [key]: { "$in": inMatchList } }) } else { res.push({ [key]: value }) } } query['$match'] = { "$and": res } return query } const payload = { id: 1, name: 'Alfred', location: 'moon', values: [{ name: 'u', age: 9 }] } // 运行输出与预期结构完全一致 console.log(JSON.stringify(queryFormat(payload)))
运行输出结果
{"$match":{"$and":[{"id":1},{"name":"Alfred"},{"location":"moon"},{"values":{"$in":[{"name":"u"},{"age":9}]}}]}}
内容的提问来源于stack exchange,提问作者AsZik
相关产品推荐
相关产品推荐

