如何从MongoMapper Plucky :: Query对象获取原始Mongo数据结果?

时间:2013-02-27 20:35:33

标签: ruby mongodb mongomapper mongodb-query

假设我们有一个名为“images”的MongoDB集合,以及一个带有相应“Image”模型的MongoMapper驱动的应用程序。如果我们使用此模型设置MongoMapper查询,我们会看到它是Plucky::Query类型并返回类型为Image的结果:

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

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

我们可以通过访问MongoMapper.connection直接在Mongo适配器上运行相应的查询,主要是绕过MongoMapper。如果我们这样做,查询的类型为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(特别是命名范围)的功能来构建查询,所以我最终得到的是{ {1}}。但后来我希望结果是普通的数据对象,而不是模型,因为我需要的只是数据,而且我不想要模型实例化的开销。

2 个答案:

答案 0 :(得分:1)

MongoMapper通过在plucky查询上设置“transformer”lambda来实现转换。您可以在MongoMapper source code

中看到这一点
def query(options={})
    query = Plucky::Query.new(collection, :transformer => transformer)
    ...
end

...

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

因此,在每次mongo文档检索之后,这个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 :(得分:1)

如果您放入驱动程序,默认情况下转换器为nil

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