2012-03-27 149 views
9

我想在MongoDb中进行高效的查询,以查找所有在用户组中列出其用户标识的用户。理想情况下,我想把它作为对Mongodb的单个请求。 我想要的对应于SQL中的嵌套选择。 我在蒙戈外壳试过这样:如何在嵌套的Sql select查询中工作嵌套的MongoDb查询

db.user.save({_id:"u1", Name:"u1 name"}); 
db.user.save({_id:"u2", Name:"u1 name"}); 
db.user.save({_id:"u3", Name:"u3 name"}); 
db.usergroup.save({_id:"g1", Users: ["u2","u3"]}); 

现在这里是选择我想做的事,但没有硬编码[“U2”,“U3”]数组:

db.user.find({_id:{$in:["u2","u3"]}}).forEach(printjson); 

这工作正常并返回u2和u3的用户对象。

现在的问题是如何获取用查询提取的$ in操作符中的userid数组,以便可以使用单个请求来创建整个查询。

A “嵌套查询” 像这样不工作:

db.user.find({_id:{$in:db.usergroup.find({_id:"g1"},{_id:0,Users:1})}}).forEach(printjson); 

给出了这样的错误: 周二3月27日6时17分41秒未捕获的异常:错误:{ “$ ERR”: “无效查询” ,“代码”:12580} 未能加载:mongoNestedSelect.js

1)这是可能的在mongodb和如何?

2)如何用官方的c#驱动程序做到这一点?

回答

5

在MongoDB中对这些问题的回答通常是使数据非规范化。如果您只需要组中用户的列表,则可以将用户名存储在组文档中的用户名。在某些方面,您可以根据您希望在屏幕上看到的结果构建数据库,而不是试图将其放入某种标准格式。

很明显,只有当您的用户组列表(带有名称)可以放在单个文档中时才有效,但您当前的方法对于组的最大大小也有一些限制。

另一种方法是将用户所属的组存储在每个“用户”文档的数组中。在该阵列字段中添加索引,现在可以按组查找用户。考虑到用户可能属于较少的组而不是组中的成员,这可能是这里最好的方法。

db.user.save({_id:"u1", name:"u1 name", groups:[{_id:"g1", name:"Group One"}, ...]}); 

同样,你可以存储组的名称与它的_id让您可以立即显示用户属于同一个往返组的列表。当然,如果你允许组名改变,你将不得不启动一个后台任务来修复所有这些名称的副本。

我也会使用内置的MongoDB id生成器而不是你自己的,它有很多理想的属性。

+0

好,谢谢。所以“真正的嵌套查询”在MongoDB中是不可能的。是的,我同意你对ObjectIds的评论,但我只是在这个例子中使用了字符串来保持简单。 – ssn 2012-03-27 06:58:03

+0

正确的是,没有嵌套的查询,您的数据需要进行结构化,以便您可以通过对数据库的单个(或最少数量)请求获得所需的结果。 – 2012-03-27 16:29:48

5

定义功能

function bbb(){ 
    var org_ids = new Array(); 
    var orgs = 
     db.orgTreeNode.find({ancestors:"ca5cd344-ba47-4601-a07b-ea2c684bfb4e"},{"_id":1}); 
    orgs.forEach(function(org){ 
     org_ids.push(org._id); 
    }) 

    return db.user.find({"org":{$in:org_ids}}).skip(300).limit(10); 
} 

执行功能

bbb() 
1

如果它可以触发让你ans--

db.users.find({ 
    _id: { 
     $in: db.logs.find({ 
      loggedbyuser: { 
       $ne: ObjectId("569f9d093447ee781ca80b52") 
      }, 
      logtype: "marketfetched", 
      "logcreated": { 
       $gt: new ISODate("2016-02-06T00:00:00.871Z") 
      } 
     }, { 
      loggedbyuser: 1, 
      _id: 0 
     }).sort({ 
      'logcreated': -1 
     }).map(function(like) { 
      return like.loggedbyuser; 
     }) 
    } 
}).map(function(like) { 
    return like.fullname; 
}); 
+1

op正在询问类似于SQL的嵌套查询,该查询只在DB内的一个步骤中执行。您只是获取“嵌套”查询的结果,并再次通过网络发送它。 – 2016-06-15 16:24:15

1

-sUReN

SQL查询:(由不同&次数群)

select city,count(distinct(emailId)) from TransactionDetails group by city; 

等效蒙戈查询应该是这样的:

db.TransactionDetails.aggregate([ 
{$group:{_id:{"CITY" : "$cityName"},uniqueCount: {$addToSet: "$emailId"}}}, 
{$project:{"CITY":1,uniqueCustomerCount:{$size:"$uniqueCount"}} } 
]);