MongoDB如何按条件返回嵌套字段子集?含批量查询场景
MongoDB Schema迁移与批量查询优化问题
我正计划将数据从JSON文件迁移至MongoDB,当前设计的Schema结构如下:
{ "slug": "string", "transcriptions": [ { "system": "foo", "text": "bar", "is_main": true, "generator": "something", "source": "human" } ], "pronunciations": [ { "system": "foo", "text": "bar", "is_main": true, "generator": "something", "source": "human" } ], "definitions": [ { ... } ] }
需要批量查询指定的1000个slug对应的文档,且仅返回每个文档中transcriptions和pronunciations数组里is_main: true的元素。之前尝试的查询语句会返回数组全部元素,无法满足需求,尝试过的语句如下:
db.words.find({ slug: ['hello', 'world', ...moreWords] }, { slug: 1, 'transcriptions.$': 1, 'pronunciations.$': 1, })
db.words.find({ slug: { $in: ['a', 'b', ...] }, transcriptions: { $: { is_main: true } }, pronunciations: { $: { is_main: true } } })
正确实现方法
使用MongoDB的聚合管道,配合$filter操作符可以精准过滤数组中符合条件的元素,具体语句如下:
db.words.aggregate([ // 匹配目标slug列表 { $match: { slug: { $in: ['hello', 'world', ...moreWords] } } }, // 过滤数组,仅保留is_main为true的元素 { $project: { slug: 1, transcriptions: { $filter: { input: '$transcriptions', cond: { $eq: ['$$this.is_main', true] } } }, pronunciations: { $filter: { input: '$pronunciations', cond: { $eq: ['$$this.is_main', true] } } } } } ])
为什么之前的方法失效
- 第一个查询里的位置操作符
$只能返回数组中第一个匹配条件的元素,且MongoDB不允许在一次find投影中对多个数组使用位置操作符,要么报错,要么返回结果不符合预期。 - 第二个查询存在语法错误,
transcriptions: { $: { is_main: true } }不是合法的查询条件;即使修正为正确的数组匹配,find也无法同时过滤两个数组的所有符合条件元素,只能返回第一个匹配项。
内容的提问来源于stack exchange,提问作者Lance Pollard
相关产品推荐
相关产品推荐

