MongoDB嵌套对象数组查询:匹配指定email值的问题
MongoDB数组嵌套对象查询问题解答
为什么你的$elemMatch查询返回null?
你之前用的查询语句:
{ contact: { $elemMatch: { email: "bla@hotmail.com" } }, }
问题出在**email: "bla@hotmail.com"是把整个email字段当作字符串来匹配**,但实际上email是一个包含home、work、primary三个键的对象,自然匹配不到任何结果。
现有$or查询的有效性
你后来用的$or写法是完全可行的:
{$or: [ { "contact.email.home": "bla@hotmail.com" }, { "contact.email.work": "bla@hotmail.com" }, { "contact.email.primary": "bla@hotmail.com" } ] }
它能准确匹配contact数组中任意元素的email对象里,三个字段中任意一个等于目标值的文档,逻辑清晰且能满足需求。
更简洁的扩展性查询方式
如果后续email对象可能新增字段,不想每次都修改查询条件,可以用$objectToArray配合数组操作符来实现更通用的查询:
方式一:用$in匹配属性值
{ "contact": { "$elemMatch": { "$expr": { "$in": ["bla@hotmail.com", { "$map": { "input": { "$objectToArray": "$email" }, "in": "$$this.v" } }] } } } }
$objectToArray把email对象转成[{k: "home", v: "xxx"}, ...]的数组,再用$map提取所有v(属性值),最后用$in判断目标值是否在其中。
方式二:用$anyElementTrue判断匹配
{ "contact": { "$elemMatch": { "$expr": { "$anyElementTrue": { "$map": { "input": { "$objectToArray": "$email" }, "in": { "$eq": ["$$this.v", "bla@hotmail.com"] } } } } } } }
$map遍历email的属性值,返回每个值是否等于目标值的布尔数组,$anyElementTrue只要数组中有一个true就匹配成功。
这两种方式的优势是:无论email后续新增多少字段,查询语句都不需要修改,扩展性更强。
内容的提问来源于stack exchange,提问作者malfoy
相关产品推荐
相关产品推荐

