如何使用MongoDB选择子文档

Mus*_*ush 11 database mongodb cakephp-2.0

我有一个带有子文档标签的集合,如:

Collection News :
   title (string)
   tags: [tag1, tag2...]
Run Code Online (Sandbox Code Playgroud)

我想选择所有以模式开头的标签,但只返回匹配的标签.

我已经使用了正则表达式,但它返回包含匹配标记的所有新闻,这里是查询:

db.news.find( {"tags":/^proga/i}, ["tags"] ).sort( {"tags":1} ).
    limit( 0 ).skip( 0 )
Run Code Online (Sandbox Code Playgroud)

我的问题是:如何检索与模式匹配的所有标签(仅限)?(最终目标是创建一个自动填充字段)

我也试过使用distinct,但是我没有找到一种方法来与查找做出明显区分,它总是返回我所有的标签:(

谢谢你的时间

Mar*_*ian 13

派对有点晚了,但希望能帮助其他寻求解决方案的人.我已经找到了一种方法,使用聚合框架并将$ project和$ unwind与$ match组合在一起,将它们链接在一起.我已经使用PHP完成了它,但你应该得到要点:

    $ops = array(
        array('$match' => array(
                'collectionColumn' => 'value',
            )
        ),
        array('$project' => array(
                'collection.subcollection' => 1
            )
        ),
        array('$unwind' => '$subCollection'),
        array('$match' => array(
                subCollection.subColumn => 'subColumnValue'
            )
        )
    );
Run Code Online (Sandbox Code Playgroud)

第一个匹配和项目只是用于过滤以使其更快,然后子集合上的展开会按项目吐出每个子集合项目,然后可以使用最终匹配对其进行过滤.

希望有所帮助.

更新(来自Ryan Wheale):

然后$group,您可以将数据恢复为其原始结构.这就像有一个$elemMatch返回多个子文档:

array('$group' => array(
        '_id' => '$_id',
        'subcollection' => array(
            '$push' => '$subcollection'
        )
    )
);
Run Code Online (Sandbox Code Playgroud)

我将其从Node转换为PHP,所以我没有在PHP中测试过.如果有人想要Node版本,请在下面留下评论,我将有责任.


mne*_*syn 10

嵌入式文档不是集合.看看你的查询:db.news .find将从news集合中返回文档.tags不是集合,也不能过滤.

这个"虚拟收藏功能"(SERVER-142)有一个功能请求,但是不要期望太快看到这个,因为它是"计划但未安排".

您可以在客户端进行过滤,或将标记移动到单独的集合中.通过只检索字段的子集 - 只有tags字段 - 这应该相当快.

提示:你的正则表达式使用了/i标志,这使得无法使用索引.你的db字符串应该是case-normalized(例如全部大写)