2015-03-02 70 views
2

我有喜歡的文檔集合如下:查找MongoDB的文件由子文檔大小

{ 
    "_id" : ObjectId("..."), 
    "some_key" : "some_value", 
    ..., 
    "another_key" : { 
     "a key" : "a value", 
     ... 
    } 
} 

有跡象表明,進入這個集合,最大的區別在「another_key」發生了幾個不同類型的文檔領域。

我希望能夠根據「another_key」中子文檔的大小找到文檔。如果它是一個數組,我可以使用這個查詢:

{ 
    "another_key" : { 
     $size : 0 
    } 
} 

找到它已被留空的所有文件。不幸的是,按照the documentation這隻適用於陣列。

有沒有辦法做到這一點的子文件?

+0

嵌套的對象不是真正的子文檔,因此不應該被稱爲子文檔,因爲它們不像個文件,並且不能使用$運算符。我會建議將another_key轉換爲如下所示的對象數組(子文檔):{key:'akey,value:'avalue'}。你現在可以找到$尺寸,如果你想要的話可​​以找到鑰匙。 db.collection.find({'another_key.key':'aKey})等等。 – 2015-03-03 00:02:00

+1

你能解釋一下這個用例嗎?誠實地說,想做這樣的事很奇怪,我想知道總體目標是什麼。也許有更好的方法?使用'$ where'通常是一個非常糟糕的主意。 – wdberkeley 2015-03-03 19:32:42

+0

@wdberkeley我的特殊使用案例是我正在使用其他人提供的數據,並且我想編寫一個腳本來驗證數據在代碼更新時不會混亂。在我的情況下,我可以檢查它是空的,但我想知道更普遍的問題。 – 2015-03-03 20:27:20

回答

1

使用Object.keys獲取子文檔鍵和$where運算符。

db.collection.find({ 
    'timestamp': "your value", 
    '$where': function() { return Object.keys(this.another_key).length === 0; } 
}) 
+1

$哪裏不是非常高性能,並且在大型集合上的速度會非常慢。 – 2015-03-03 00:17:03

1

嵌套的對象不是真正的子文檔,我不把它們稱爲子文檔,因爲它們並不像一個文件,並在其上不能使用$運營商。另外,索引功能對它們並不起作用,但是我們可以將'another_key.key'編入索引以獲得更好的搜索性能。

我建議轉another_key成看起來像物體(子文檔)的數組:

db.items.insert({ 
    some_key : 'some_value', 
    another_key : [ 
     {key: 'akey', value: 'avalue'}, 
     {key: 'bkey', value: 'bvalue'} 
    ] 
}); 

您可以通過$大小,關鍵如果你想現在發現。

mongos> db.items.find({another_key: {$size: 0}}) 
// 0 documents 
mongos> db.items.find({another_key: {$size: 1}}) 
// 0 documents 
mongos> db.items.find({another_key: {$size: 2}}) 
{ "_id" : ObjectId("54f62a48e2fdcc95d4934424"), "some_key" : "some_value", "another_key" : [ { "key" : "akey", "value" : "avalue" }, { "key" : "bkey", "value" : "bvalue" } ] } 
mongos> db.items.find({another_key: {$size: 3}}) 
// 0 documents 

mongos> db.collection.find({'another_key.key': 'akey'}) 
{ "_id" : ObjectId("54f62a48e2fdcc95d4934424"), "some_key" : "some_value", "another_key" : [ { "key" : "akey", "value" : "avalue" }, { "key" : "bkey", "value" : "bvalue" } ] } 

不幸的是你不能做比較性$size查詢:

mongos> db.items.find({another_key: {$size: {$gt:1} } }) 
error: { 
    "$err" : "Can't canonicalize query: BadValue $size needs a number", 
    "code" : 17287 
}