2014-06-12 73 views
0

我需要執行mongoDB查詢來獲取日期之間的用戶狀態。MongoDB使用條件返回數組

這是一個文檔例如:

{ 
    "_id" : ObjectId("538efd918163b19307c59e8e"), 
    "username" : "admin", 
    "hashedPassword" : "9qm4ufCPOCeU4AoBIMCJyf8oIvs8vWUYKIbImhc1N9HJrRKzCwCbeGNBsuOWnQ2kMbM635KmingRkn31wvHPQ/1bvs8Msg2rUchybaVvFmpy15A9Pnhb1BDHSLPftn0v8mSyhZQuOpP7Goirg07CGDPvJQqhN6oH6g0+iBTliAs=", 
    "salt" : "EHLY4edLmrq7Nj4zRqh7Loow/O34pHNiWQ1i4vo8+SJTl82phMokAyTSr4MNKBeMMhJgCof1uK+3++PlXp5Y3I0SL3XkzJsSWG9K5oXJCE7B3j0Kazj4IlAllOEcXwMeuBVTnTgnBi9pUqdWyDysHG893oMVmr3VizycL/Iz484=", 
    "realName" : "Administrator", 
    "roles" : [ 
     "admin", 
     "operator", 
     "technician" 
    ], 
    "status" : [], 
    "states" : [ 
     { 
      "status" : "vacances", 
      "date" : ISODate("2014-06-09T11:42:02.756Z") 
     }, 
     { 
      "status" : "busy", 
      "date" : ISODate("2014-06-09T11:42:03.443Z") 
     }, 
     { 
      "status" : "eating", 
      "date" : ISODate("2012-06-09T11:42:04.080Z") 
     }, 
     { 
      "status" : "busy", 
      "date" : ISODate("2014-06-09T11:49:53.765Z") 
     }, 
     { 
      "status" : "vacances", 
      "date" : ISODate("2014-06-09T11:49:54.402Z") 
     }, 
     { 
      "status" : "eating", 
      "date" : ISODate("2014-06-09T11:49:56.409Z") 
     }, 
     { 
      "status" : "resting", 
      "date" : ISODate("2014-06-09T11:49:57.114Z") 
     }, 
     { 
      "status" : "eating", 
      "date" : ISODate("2014-06-09T12:24:38.880Z") 
     }, 
     { 
      "status" : "busy", 
      "date" : ISODate("2014-06-09T14:51:13.440Z") 
     }, 
     { 
      "status" : "free", 
      "date" : ISODate("2014-06-09T14:51:20.940Z") 
     }, 
     { 
      "status" : "vacances", 
      "date" : ISODate("2014-06-12T11:05:36.448Z") 
     }, 
     { 
      "status" : "busy", 
      "date" : ISODate("2014-06-12T11:05:37.425Z") 
     } 
    ] 
} 

然後,希望得到一個日期之間的狀態,我有這個疑問:

var collection = db.collection('users'); 
    collection.aggregate([ 
     {$match: {$and: [ 
      { _id: new ObjectID(id)}, 
      { 'states.date': { $gt: new Date(from), $lte: new Date(to) }} 
     ]}}, 
     {$unwind: "$states"}, 
     {$sort: {"states.date": -1}}, 
     {$group: {_id: "$_id", states: {$push: "$states"}}} 
    ], function (e, doc) { 
     if (e) { 
      error(e); 
     } 
     success(doc); 
    }); 

結果的錯誤,因爲返回我的一切用戶的狀態,不僅在日期查詢之間。我如何減少mongodb查詢中的響應?

回答

0

您的第一個$match條件只匹配文檔而不匹配數組成員。要「過濾」,您需要實際上$match之後,您還需要$unwind

collection.aggregate([ 
     {$match: {$and: [ 
      { _id: new ObjectID(id)}, 
      { 'states.date': { $gt: new Date(from), $lte: new Date(to) }} 
     ]}}, 
     {$unwind: "$states"}, 
     {$match: {$and: [ 
      { 'states.date': { $gt: new Date(from), $lte: new Date(to) }} 
     ]}}, 
     {$sort: {"states.date": -1}}, 
     {$group: {_id: "$_id", states: {$push: "$states"}}} 
    ], function (e, doc) { 
     if (e) { 
      error(e); 
     } 
     success(doc); 
    }); 
+0

它確定。我不知道我能在其他比賽結束後做一場比賽。謝謝 – colymore

+0

@colymore由於您剛剛學到了一些東西,甚至可以解決您的問題,所以您可以放棄並接受答案。這是感謝那些幫助的人的方式。 –

+0

是的,我知道,但我可以在回覆後的第一個8分鐘內接受問題。我做到了。 – colymore

1

你應該過濾文件$unwind之後的數組。第一場比賽將匹配整個文檔,但在數組中不會過濾掉的文件:

var collection = db.collection('users'); 
    collection.aggregate([ 
     {$match: { _id: new ObjectID(id) } }, 
     {$unwind: "$states"}, 
     {$match: { 'states.date': { $gt: new Date(from), $lte: new Date(to) }}}, 
     {$sort: {"states.date": -1}}, 
     {$group: {_id: "$_id", states: {$push: "$states"}}} 
    ], function (e, doc) { 
     if (e) { 
      error(e); 
     } 
     success(doc); 
    }); 

編輯

你也不需要搜索的日期範圍在你第一次$match如果你正在尋找一個特定的用戶。僅通過_id進行篩選將在該字段上使用默認索引,並且速度會更快。