【问题标题】:How does Mongoid "criteria" work?Mongoid“标准”是如何工作的?
【发布时间】:2011-11-27 04:06:18
【问题描述】:

我正在尝试做一些直接的事情,例如:

User.all(:criteria => {:project_id => 2})

这将返回Mongoid::Criteria 的实例

我可以用这个标准做什么?如果我只想返回文档数组以供进一步评估怎么办?

【问题讨论】:

  • 所以 ActiveRecord 中的 all 返回一个数组。你想调用execute 来获取数组。 User.where(project_id: 2).execute

标签: ruby-on-rails mongodb mongoid


【解决方案1】:

Criteria 类似于ActiveRecord 中的Relation 对象

你可以这样使用它

users = User.where(:project_id => 2)
users.each do |user|
  puts user.name
end
# or
users.all

如果没有任何用户,这将返回[]

users.all.each do |user|
  puts user.name
end

【讨论】:

  • 如果没有符合该条件的用户,当我运行 puts user.name 时,我会返回 Criteria 本身。有没有办法避免这种情况?
  • 如果现在有任何用户puts user.name 将永远不会被执行
  • users.all 不返回数组。它返回另一个标准,通常不需要。要从条件中获取数组,请使用 .to_a
【解决方案2】:

要从 Mongoid::Criteria 获取数组:使用方法 .to_a

【讨论】:

    【解决方案3】:

    在 Mongoid 中,条件代表查询,而不是元素。 您可以将条件视为过滤器、范围、查询对象。

    一旦你有了一个条件(范围),你就可以获取元素,对数据库执行一个实际的查询,使用一个应该迭代元素或返回一个元素的方法,例如:.first,@ 987654322@、.to_a.each.map

    这样效率更高,允许您从其他简单的“查询”中组合出复杂的“查询”。

    例如,您可以在类中创建一些命名范围:

    class User
      include Mongoid::Document
      field :name,  type: String
      field :age,   type: Integer
      field :admin, type: Boolean
    
      scope :admins, where(admin: true) # filter users that are admins
      scope :with_name, (name)-> { where(name: name) } # filter users with that name
    end
    

    然后你可以创建一些标准对象:

    admins      = User.admins
    johns       = User.with_name('John')
    admin_johns = User.admins.with_name('John') # composition of criterias, is like doing ANDs
    young       = User.where(:age.lt => 25) # the Mongoid method .where also returns a criteria
    

    到目前为止,您没有向 mongo 数据库触发任何查询,您只是在编写查询。

    您可以随时保持链接条件,以进一步细化查询:

    young_admins = admins.merge(young)
    old_admins = admins.where(age.gt => 60)
    

    最后,获取包含元素的数组:

    # Execute the query and an array from the criteria
    User.all.to_a
    User.admins.to_a
    admins.to_a
    young_admins.to_a
    
    # Execute the query but only return one element
    User.first
    admins.first
    johns.last
    
    # Execute the query and iterate over the returned elements
    User.each{|user| ... }
    User.admins.each{|admin_user| ... }
    johns.map{|john_user| ... }
    

    因此,在 Class 中定义一些命名范围,然后使用它们创建条件,并在需要时进行真正的查询(延迟加载)。即使您不知道自己需要标准,标准也会为您处理所有这些。

    【讨论】:

      猜你喜欢
      • 2017-10-20
      • 1970-01-01
      • 2011-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-24
      • 1970-01-01
      相关资源
      最近更新 更多