2013-02-27 25 views
1

比方說,我們有一個名爲「圖像」的MongoDB集合和一個具有相應「圖像」模型的MongoMapper驅動的應用程序。如果我們建立一個MongoMapper查詢中使用這個模型中,我們看到它是Image類型的類型Plucky::Query並返回結果:如何從MongoMapper Plucky :: Query對象獲取原始Mongo數據結果?

>> Image.where(:file_type => 'image/jpeg').class 
=> Plucky::Query 

>> Image.where(:file_type => 'image/jpeg').first.class 
=> Image 

我們可以蒙戈適配器上直接運行相應的查詢,大多繞過MongoMapper,由訪問MongoMapper.connection。如果我們這樣來做,查詢是Mongo::Cursor類型,並返回BSON::OrderedHash類型的原始數據結果:

>> MongoMapper.connection.db(dbname).collection('images').find({ :file_type => 'image/jpeg' }).class 
=> Mongo::Cursor 

>> MongoMapper.connection.db(dbname).collection('images').find({ :file_type => 'image/jpeg' }).first.class 
=> BSON::OrderedHash 

的問題是,有沒有辦法採取Plucky::Query像上面並把它轉換到(或檢索從它)一個基本的,非擴展的Mongo::Cursor對象?

起初,我以爲我找到了find_each一個解決方案,並實際採取Plucky::Query並返回一個Mongo::Cursor

>> Image.where(:file_type => 'image/jpeg').find_each.class 
=> Mongo::Cursor 

但事實證明,這Mongo::Cursor以某種方式延長或從上面的一個,否則不同它仍然會返回Image對象,而不是BSON::OrderHash對象:

>> Image.where(:file_type => 'image/jpeg').find_each.first.class 
=> Image 

更新:我不能簡單地繞過MongoMapper查詢魔法中音和第二種情況一樣,因爲我需要訪問MongoMapper的功能(特別是命名範圍)來建立查詢,所以我最終得到的結果是Plucky::Query。但是,我希望結果是簡單的數據對象,而不是模型,因爲我需要的只是數據,並且我不希望模型實例化的開銷。

回答

1

MongoMapper通過在plucky查詢中設置「變換器」lambda來實現轉換。您可以在MongoMapper source code看到:

def query(options={}) 
    query = Plucky::Query.new(collection, :transformer => transformer) 
    ... 
end 

... 

def transformer 
    @transformer ||= lambda { |doc| load(doc) } 
end 

所以每個蒙戈文獻檢索後,該Plucky::Query運行加載模式的轉變。看看Plucky source code我們看到有一個簡單的setter方法[]我們可以用來禁用這個。因此,這是解決方案:

plucky_query = Image.where(:file_type => 'image/jpeg') 

plucky_query.first.class 
# => Image 

plucky_query[:transformer] = nil 
plucky_query.first.class 
# => BSON::OrderedHash 

如果你不介意的猴子打補丁可以封裝像這樣:

module Plucky 
    class Query 
     def raw_data 
      self[:transformer] = nil 
      self 
     end 
    end 
end 

然後,你可以簡單地寫:

Image.where(:file_type => 'image/jpeg').raw_data.first.class 
# => BSON::OrderedHash 
1

如果您掉到驅動器,默認變壓器爲nil

1.9.3p194 :003 > Image.collection.find({ :file_type => 'image/jpeg' }, { :limit => 1 }).first.class 
=> BSON::OrderedHash 
+0

謝謝,但這不適用於我的情況,因爲我想使用MongoMapper的功能來構建原始查詢。我更新我的問題來詳細說明這一點。 – 2013-02-27 21:15:54