2012-03-27 154 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"}} } 
]);