如何使用MongoDB选择子文档

如何使用MongoDB选择子文档,mongodb,cakephp-2.0,database,Mongodb,Cakephp 2.0,Database,我有一个带有子文档标记的集合,如: 我想选择所有以模式开头的标记,但只返回匹配的标记 我已经使用了正则表达式,但它返回包含匹配标记的所有新闻,以下是查询: db.news.find( {"tags":/^proga/i}, ["tags"] ).sort( {"tags":1} ). limit( 0 ).skip( 0 ) 我的问题是:如何检索(仅)与模式匹配的所有标记? (最终目标是生成一个自动完成字段) 我也尝试过使用distinct,但我没有找到一种使用find创建distin

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

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

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

db.news.find( {"tags":/^proga/i}, ["tags"] ).sort( {"tags":1} ).
    limit( 0 ).skip( 0 )
我的问题是:如何检索(仅)与模式匹配的所有标记? (最终目标是生成一个自动完成字段)

我也尝试过使用distinct,但我没有找到一种使用find创建distinct的方法,它总是返回我所有的标记:(


感谢您抽出时间

嵌入的文档不是集合。请查看您的查询:db。新闻。查找将返回来自
新闻
集合的文档。
标记
不是集合,无法筛选

此“虚拟收藏功能”(virtualcollection feature)有一个功能请求,但不要期望很快看到它,因为它是“已计划但未计划的”

您可以在客户端进行筛选,或者将标记移动到单独的集合中。通过-仅通过
标记
字段-这应该相当快


提示:您的正则表达式使用
/i
标志,这使得无法使用索引。您的db字符串应该大小写规范化(例如,所有大写)

聚会有点晚了,但希望能帮助其他正在寻找解决方案的人。我找到了一种方法,使用聚合框架,将$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'
            )
        )
    );
第一个匹配项和项目仅用于过滤以加快速度,然后子集合上的“展开”会逐项吐出每个子集合,然后可以使用最终匹配项进行过滤

希望有帮助

更新(来自Ryan Wheale):

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

array('$group' => array(
        '_id' => '$_id',
        'subcollection' => array(
            '$push' => '$subcollection'
        )
    )
);

我把这个从Node翻译成了PHP,所以我还没有用PHP测试过。如果有人想要这个Node版本,请在下面留下评论,我会很乐意的。

谢谢你的回答,我会尝试制作另一个集合“tags”,它可以包含我所有的标签,并对这个集合进行过滤(但不确定它是以NOSQL的方式)哥们,纯粹的天才。我无法描述我发现这个东西时灯泡爆炸的情况。你也可以
$group
将项目重新组合到其原始结构中。我需要的是相当于
$elemMatch
的投影,它将返回比第一个结果更多的结果。谢谢!!
array('$group' => array(
        '_id' => '$_id',
        'subcollection' => array(
            '$push' => '$subcollection'
        )
    )
);