2012-01-14 63 views
11

选择子文档我有一个集合与子文档标签像:如何使用MongoDB的

Collection News : 
    title (string) 
    tags: [tag1, tag2...] 

我要选择谁所有带有图案启动标签,但只返回匹配的标签。

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

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

我的问题是:我怎样才能检索到所有的标签(只),谁的模式相匹配? (最终目标是使自动完成场)

我也使用不同的尝试,但我没有找到一种方法,使一个独特的带的发现,它总是返回我所有的标签:(

感谢您的时间

回答

10

嵌入式文件都没有收藏看看你的查询:。DB 新闻 .find将从news集合返回文档tags不是一个集合,并不能过滤

。我在那里这是针对这个“虚拟收集功能”(SERVER-142)的功能请求,但不要期望看到这个过早,因为它是“已计划但未计划的”。

您可以过滤客户端,或将标签移动到单独的集合。由retrieving only a subset of fields - 只有tags字段 - 这应该是相当快。

提示:您的正则表达式使用/i标志,这使得不可能使用索引。你的db字符串应该是大小写正常化的(例如全部大写)

+0

感谢您的回答,我会尽量让另一个集合“标签”女巫可以包含我所有的标签,并在这一个上做过滤器(但不确定它是否以NOSQL方式) – Mush 2012-01-14 19:19:00

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' 
      ) 
     ) 
    ); 

第一场比赛和项目只是用它来过滤掉,使其更快,然后子集合开卷逐项吐出每一个子集合项目其然后可以使用最终匹配进行过滤。

希望有所帮助。

UPDATE(从瑞安Wheale):

然后,您可以$group数据返回到其原来的结构。这就像一个$elemMatch它返回一个以上的子文档:

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

我翻译这个从节点到PHP,所以我没有在PHP测试。如果有人想要Node版本,请在下面留言,我会承担责任。

+1

老兄,纯粹的天才。当我发现这一点时,我无法描述灯泡熄灭。您也可以将这些项目重新组合为原始结构。我需要相当于$ elemMatch的投影,这会比第一个结果返回更多。谢谢!! – 2014-05-25 00:21:44