2014-05-22 35 views
2

我有以下的用戶對象:MongoDB的限制領域和切片投影一起

{ 
    "_id" : ObjectId("someId"), 
    "name" : "Bob", 
    "password" : "fakePassword", 
    "follower" : [...], 
    "following" : [..] 
} 

我需要分頁在跟蹤器列表,所以我用切片投影算,但我只需要分頁的追隨者名單被退回。而且我不知道我是否以錯誤的方式進行,或者這不能完成,但限制字段不適用於切片投影。

以下是幾個查詢我想:

collection.findOne(
      { 
      _id: new ObjectId(userId) 
      }, 
      { 
      follower: {$slice:[skip, parseInt(pageSize)]}, 
      follower: 1 
      },.. 

collection.findOne(
      { 
      _id: new ObjectId(userId) 
      }, 
      { 
      follower: 1, 
      follower: {$slice:[skip, parseInt(pageSize)]} 
      }, 

但這些返回的對象中的所有值,並且不限制的領域,雖然,切片工程在這兩種情況下罰款。 另外,當我做了類似_id:0,following:0的工作時,這部分工作,但我不想在這樣的查詢中提及每個字段,一旦我決定更改模式,它可能會產生問題。 我如何得到這個工作,可能是什麼語法的查詢來得到這個工作.. ??

回答

3

不確定我在這裏獲取您的使用模式。也許我們可以簡化這個例子。因此,考慮到文件:

{ 
    "_id" : ObjectId("537dd763f95ddda3208798c5"), 
    "name" : "Bob", 
    "password" : "fakePassword", 
    "follower" : [ 
      "A", 
      "B", 
      "C", 
      "D", 
      "E", 
      "F", 
      "G", 
      "H", 
      "I", 
      "J", 
      "K" 
    ] 
} 

所以簡單的查詢是這樣的:

db.paging.find(
    { "name": "Bob" }, 
    { 
     "_id": 0, 
     "name": 0, 
     "password": 0, 
     "follower": { "$slice": [0,3] } 
}).pretty() 

給出的結果:

{ 
    "follower" : [ 
      "A", 
      "B", 
      "C" 
    ] 
} 

而且同樣可以從以下頁面:

db.paging.find(
    { "name": "Bob" }, 
    { 
     "_id": 0, 
     "name": 0, 
     "password": 0, 
     "follower": { "$slice": [3,3] } 
}).pretty() 

給出結果:

{ 
    "follower" : [ 
     "D", 
     "E", 
     "F" 
    ] 
} 

所以對我個人來說,我不知道你是否被詢問現場排除,還是你在問「尋呼」排列結果,但無論哪種方式,雙方的這些例子顯示在這裏。

+1

所以,就像在你的答案,你必須確定你需要刪除的所有字段,但根據MongoDB的文檔,你可以也只是指定你需要的字段,比如'followers:1',這樣只會給我跟隨者字段和_id字段,而且我不必指定其他我不需要的字段。我需要這個與切片投影算子一起工作。 –

+2

@SambhavSharma如果這是你真正的問題,那麼我會愉快地提交文檔補丁(已經是貢獻者),但沒有這個實際上不以這種方式工作。您需要明確排除使用'$ slice'時不需要的所有字段。你也不能在'.find()'中混合包含和排除,如果你需要這種複雜性,那麼你可以使用['.aggregate()'](http://docs.mongodb.org/manual/reference/method/db。 collection.aggregate /)替換爲[**'$ project' **](http://docs.mongodb.org/manual/reference/operator/aggregation/project/)運算符。 –

2

一種方式是實際說{_id:1}這裏使用_id:

{ "_id" : ObjectId("537de1bc08eb9d89a7d3a1b2"), "f" : [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20 ], "d" : 1 } 
> db.test.findOne({ "_id" : ObjectId("537de1bc08eb9d89a7d3a1b2")},{f:{$slice:[0,2]}}) 
{ 
     "_id" : ObjectId("537de1bc08eb9d89a7d3a1b2"), 
     "f" : [ 
       1, 
       2 
     ], 
     "d" : 1 
} 
> db.test.findOne({ "_id" : ObjectId("537de1bc08eb9d89a7d3a1b2")},{_id:0, f:{$slice:[0,2]}}) 
{ "f" : [ 1, 2 ], "d" : 1 } 
> db.test.findOne({ "_id" : ObjectId("537de1bc08eb9d89a7d3a1b2")},{_id:1, f:{$slice:[0,2]}}) 
{ "_id" : ObjectId("537de1bc08eb9d89a7d3a1b2"), "f" : [ 1, 2 ] } 
+0

我認爲這應該是正確的答案。另外如果你絕對不想_id,你可以設置_id:0和一些nonexistent_field:1。然而,在返回的文檔中使用_id似乎不太可能會成爲問題。還有一件事;如果您在像sub_doc.my_array這樣的子文檔中進行切片:{$切片...},則需要在該級別選擇一個不存在的字段,如sub_doc.nonexistant_field:1以防止獲得更多片段 – Keith