2017-06-15 61 views
1

我試圖將聚合從MongoDB shell轉換爲使用Mongoid作爲ODM的ruby代碼。使用mongoid統計數組大小

我有這樣的(很簡單的例子)的一些文件:

{ 
    "name": "Foo", 
    "tags": ["tag1", "tag2", "tagN"] 
}, 
{ 
    "name": "Bar", 
    "tags": ["tagA", "tag2"] 
}, 
... 

現在我想獲得與名稱字段和每個標籤總數的所有文件。

在MongoDB的外殼,我可以用這樣的聚合框架實現它:

db.documents.aggregate(
    {$project: {name: 1, tags_count: {$size: $tags}} 
) 

,它將返回:

[{"name": "Foo", "tags_count": 3}, 
{"name": "Bar", "tags_count": 2}] 

現在令人沮喪的,我想實現相同在使用Mongoid作爲ODM的rails應用程序中進行查詢。

的代碼如下所示(使用Rails控制檯):

Document.collection.aggregate(
    [ 
    {'$project': {name: 1, tags_count: {'$size': '$tags'}}} 
    ] 
).to_a 

它返回一個錯誤:

Mongo::Error::OperationFailure: The argument to $size must be an Array, but was of type: EOO (17124)

我的問題是:如何讓我Mongoid明白$tags參考了正確的領域?或者我從代碼中錯過了什麼?

感謝

+1

看起來你的數據實際上並不包含數組,或者可能不一致。出於同樣的原因,相同的語句在相同數據的shell中會失敗。 –

回答

1

它看起來像有是不持續在該領域的陣列數據。爲此,您可以使用$ifNull放置一個空數組,其中沒有被發現,從而返回$size0:在所有使用$exists

Document.collection.aggregate(
    [ 
    {'$project': {name: 1, tags_count: {'$size': { '$ifNull': [ '$tags', [] ] } } }} 
    ] 
).to_a 

或者你可以直接跳過其中的字段不存在:

Document.collection.aggregate(
    [ 
    {'$match': { 'tags_count': { '$exists': true } } }, 
    {'$project': {name: 1, tags_count: {'$size': '$tags'}}} 
    ] 
).to_a 

但是,當然,這將過濾這些文件的選擇,這可能會或可能不是所需的效果。