【问题标题】:How to query MongoDB directly from Ruby instead of using Mongoid?如何直接从 Ruby 查询 MongoDB 而不是使用 Mongoid?
【发布时间】:2013-01-26 20:03:18
【问题描述】:

我正在为使用 MongoDB 和 Mongoid 的 Rails 应用程序编写迁移。我的迁移目前使用我的模型,这些模型使用 Mongoid 来查询和更新记录,但性能低于标准。我本质上是在更新大型集合中的所有记录并进行 n+20 次查询。我花了一个小时在本地运行(但没有完成)后终止了迁移。我希望能够毫不费力地对 mongo 运行原始查询。我假设有一些方法可以从 Mongoid 访问 mongo 驱动程序,因为 Mongoid 已经加载了与数据库的连接。如何访问数据库以直接运行我的更新查询?

【问题讨论】:

  • 在 mongoid 3 或 2 上运行,如果 2 它与轻便摩托车不同的适配器无法记住名称,但我猜是 mongodb-ruby-driver
  • 是的,我正在使用 mongoid 3

标签: ruby-on-rails mongodb mongoid


【解决方案1】:

简短的回答是Moped。这是构建 Mongoid 的较低级别的 API,如果您已经使用 Mongoid,它将可用。 Moped API 是原始 MongoDB 操作的精简包装器。这里的文档:http://mongoid.org/en/moped/docs/driver.html 应该很有用。

【讨论】:

  • 我是这么想的,但是怎么才能访问呢?在文档中,示例显示Moped::Session.new(host).use(database),但此信息已在 Mongoid 自动加载的配置文件中定义。我应该能够从 Mongoid 访问某种 Moped 对象。我只是不知道怎么做。
  • 你应该能够从 Mongoid 获得它:Mongoid::Sessions.default 将返回一个 Moped::Session,你可以从中进行所有的助力车操作。
【解决方案2】:

你是怎么做的(这也适用于 2+ 和 3+)

1) 您的所有模型都表现出这种行为,您在所有模型中都有 include Mongoid::Document,因此从技术上讲,每个文档都通过 moped 或 mongodb-ruby 驱动程序通过 mongoid 映射到 monogodb 中

所以如果你有模特喜欢

class PerformerSource 
  include Mongoid::Document
  ## Definition

end

现在您可以像这样使用驱动程序(Moped 或 Mongodb-ruby 驱动程序)运行 Mongo Query

PerformerSource.collection.insert("something")
## where something is json document you want to insert

这将为您提供该文档的轻便摩托车(如果使用 mongoid 3)连接

2) 你也可以这样做

 Mongoid::Sessions.default.collections.find { |document| document.name == "performer_sources"}.insert("something")

如何更多地了解 mongo 查询以及 mongoid 如何映射那些使用 moped 的用户,您可以关注 this 查询部分,其中描述了如何通过 moped 在内部实现查询

希望有帮助

【讨论】:

  • 被标记为答案的那个只在rails console中有效,而这个在Model中有效。我正在使用 Mongoid 4.0.2。
【解决方案3】:

如果您使用的是 Mongoid 3,它可以轻松访问其 MongoDB 驱动程序:Moped。下面是一个在不使用模型访问数据的情况下访问一些原始数据的示例:

db = Mongoid::Sessions.default

# inserting a new document
collection = db[:collection_name]
collection.insert(name: 'my new document')

# finding a document
doc = collection.find(name: 'my new document').first

# iterating over all documents in a collection
collection.find.each do |document|
  puts document.inspect
end

【讨论】:

  • 嗨安德鲁,你的回答很有用,但我正在使用 mongoid 并直接访问你的回答中提到的集合,它工作得很好,但是在使用像 Model.save 这样的 mongoid activerecord 操作之后, Model.update_attributes 等不工作,你能建议一些解决方案吗?
  • 如果不看一些代码示例,很难知道发生了什么。我认为您应该将此作为您自己的问题发布并包含代码示例。
  • 感谢安德鲁的回复,但我找到了原因并解决了同样的问题。
  • 我觉得有必要提一下,如果文件是像 test.rb 这样的脚本,你必须设置`require 'mongoid'`
  • 注意:客户端仅在您连接到数据库时才会显示。否则它会说NameError: uninitialized constant Mongoid::Sessions
【解决方案4】:

就像这里提到的任何人一样,您的答案是助力车。 这是我的 ruby​​ 脚本示例(简单文件 test.rb)

  1. 定义一个 mongoid.yml(在本例中,在 localhost)
development:
  sessions:
    default:
      database: test_development
      hosts:
        - localhost:27017
      options:
  1. 设置加载配置和测试集合

    #!/usr/bin/env ruby 需要'mongoid'

    Mongoid.load!("path/to/file/mongoid.yml",:development) # :development对应mongoid.yml第一行环境 db = Mongoid::Sessions.default puts "Collection documents count :> #{db[:collection].find.count}"

【讨论】:

    【解决方案5】:

    对于 Mongoid 5:

    db = Mongoid::Clients.default
    
    collection = db[:collection_name]
    

    现在我们可以对集合执行查询

    【讨论】:

      【解决方案6】:

      如果您使用 mongoid 5(5),我建议您使用它。

      Item.collection.update_one({_id:  BSON::ObjectId('55512b7070722d22d3050000')}, '$set' => { 'category_name': 'Test' })
      

      解决这个问题的诀窍是 BSON::ObjectID。如果您想搜索单个 id,这就像在 mongo 查询中一样。

      db.items.update({ '_id': ObjectId("55512b7070722d22d3050000") }, { $set: {'category_name': 'Test' } })
      

      以上是查询的 mongo 版本。我发现将 ruby​​ 代码翻译成 mongo 代码是困难的部分,因为在文档中有些部分很难找到。

      http://www.rubydoc.info/gems/mongo/Mongo%2FCollection%3Aupdate_one

      【讨论】:

        【解决方案7】:

        对于 Mongoid 6:

        db = Mongoid::default_client
        collection = db[:collection_name]
        

        【讨论】:

          猜你喜欢
          • 2011-06-14
          • 2013-07-31
          • 1970-01-01
          • 2021-04-05
          • 1970-01-01
          • 2021-02-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多