2015-04-01 50 views
0

我正在使用mongoid進行mongodb聚合,使用ModleName.collection.aggregate(pipeline)。返回的值是一個數組而不是Mongoid::Criteria,因此如果在陣列上執行first,則會得到類型爲BSON::Document而不是ModelName的第一個元素。結果,我無法將它用作模型。Ruby mongoid聚合返回對象

是否有一種方法可以從聚合中返回一個條件而不是數組,或將bson文檔轉換爲模型實例?

使用mongoid(4.0.0)

+0

你可以顯示查詢思考其他...? – 2015-04-01 11:04:25

回答

1

我一直在爲自己努力掙扎。恐怕你必須自己建立你的「模型」。讓我們從我的代碼示例:

class Searcher 
    # ... 

    def results(page: 1, per_page: 50) 
    pipeline = [] 

    pipeline << 
     "$match" => { 
     title: /#{@params['query']}/i 
     } 
    } 

    geoNear = { 
     "near"    => coordinates, 
     "distanceField"  => "distance", 
     "distanceMultiplier" => 3959, 
     "num"    => 500, 
     "spherical"   => true, 
    } 

    pipeline << { 
     "$geoNear" => geoNear 
    } 

    count = aggregate(pipeline).count 

    pipeline << { "$skip" => ((page.to_i - 1) * per_page) } 
    pipeline << { "$limit" => per_page } 

    places_hash = aggregate(pipeline) 

    places = places_hash.map { |attrs| Offer.new(attrs) { |o| o.new_record = false } } 

    # ... 

    places 
    end 

    def aggregate(pipeline) 
    Offer.collection.aggregate(pipeline) 
    end 
end 

我省略了很多從原來的項目代碼,只是提出了我一直在做的方式。

最重要的這裏曾是行:

places_hash.map { |attrs| Offer.new(attrs) { |o| o.new_record = false } } 

都在哪裏我創建的Offers陣列,但另外,手動我自己new_record屬性設置爲false,所以他們的行爲像任何其他文件通過簡單Offer.where(...)得到。

這不是很美,但它對我很有用,而且我可以充分利用整個Aggregation Framework!

希望有幫助!

+0

我也遇到同樣的限制。在你的例子中,你可以使用'Model :: instantiate'而不是'new'來避免處理'new_record'標誌,例如:'places_hash.map {| attrs | Offer.instantiate(attrs)}'。 – 2015-04-20 21:41:16

+0

嗨@kardeiz,謝謝你的提示!你是什​​麼意思的限制?這不適合你嗎? – 2015-04-21 06:37:27