我想在MongoDb中进行高效查询,以查找在用户组中列出其用户ID的所有用户。理想情况下,我想将此作为对Mongodb的单个请求。 我想要的对应于SQL中的嵌套选择。 我在mongo shell中试过这个:
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数组,以便可以使用单个请求创建整个查询。
像这样的“嵌套查询”不起作用:
db.user.find({_id:{$in:db.usergroup.find({_id:"g1"},{_id:0,Users:1})}}).forEach(printjson);
给出了这个错误: Tue Mar 27 06:17:41未捕获异常:错误:{“$ err”:“无效查询”,“代码”:12580} 无法加载:mongoNestedSelect.js
1)这可能在mongodb中有用吗?
2)如何使用官方c#驱动程序执行此操作?
答案 0 :(得分:7)
MongoDB中对此类问题的回答通常是对数据进行非规范化。如果您只需要组中的用户列表,则可以在组文档中存储用户ID 和用户名。在某些方面,您可以根据要在屏幕上看到的结果来构建数据库,而不是尝试将其放在某种标准化格式中。
显然,只有当您的用户组列表(带有名称)可以放在单个文档中时才会起作用,但您当前的方法在组的最大大小方面也存在一些限制。
另一种方法是将用户所属的组存储在每个“用户”文档的数组中。在该数组字段上添加索引,现在您可以按组查找用户。鉴于用户可能属于较少的群组而不是群组中的成员,这可能是最好的方法。
db.user.save({_id:"u1", name:"u1 name", groups:[{_id:"g1", name:"Group One"}, ...]});
同样,您可以使用_id存储组名,以便您可以通过单次往返立即显示用户所属的组列表。当然,如果您允许更改组名,则必须启动后台任务以修复该名称的所有副本。
我也会使用内置的MongoDB id生成器而不是你自己的,它有许多理想的属性。
答案 1 :(得分:7)
定义功能
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()
答案 2 :(得分:1)
如果它可以触发你的回答 -
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;
});
答案 3 :(得分:1)
-sUReN
SQL查询:(分组和不同的计数)
pd.DataFrame({k:dict.fromkeys(v,k) for k,v in dic.items()}).T.fillna("-")
# ^----- replace k with "x" to get back the first o/p
等效的mongo查询如下所示:
select city,count(distinct(emailId)) from TransactionDetails group by city;
答案 4 :(得分:0)
我想知道关于mongodb中嵌套查询的同一件事。对于我的情况,我做了一点点投入工作,我想您也可以使用“ $ or”并使用toArray()
db.user.find({$or:db.usergroup.find({_id:"g1"},{_id:0,Users:1}).toArray()})
可能不太正确,但这是我的数据使用下一个查询的示例。显然有点愚蠢,为什么在这种情况下将ID反馈回另一个查询,但想看看它是否可以工作,并且确实可以做到:
db.notification.find({$or:db.notification.find({'startDate': { '$gte': ISODate("2019-08-01") }},{_id:1}).limit(10).toArray()})
答案 5 :(得分:0)
db.usergroup.aggregate([
{ $match: { _id: "g1" } },
{ $unwind: "$Users" },
{ $lookup:
{ from: "user", localField: "Users", foreignField: "_id", as: "user" }
}
])
// result :
{ "_id" : "g1", "Users" : "u2", "user" : [ { "_id" : "u2", "Name" : "u1 name" } ] }
{ "_id" : "g1", "Users" : "u3", "user" : [ { "_id" : "u3", "Name" : "u3 name" } ] }