查找哈希字段包含给定值的条目

时间:2014-01-28 15:43:02

标签: ruby-on-rails mongodb mongoid

我的mongo数据库中有一个带有哈希值的字段,例如:

Company.find('testCompany').categories
=> {"architects"=>"architects", "landscape_designers"=>"landscape_designers"}

如何在此字段中选择.where?所以我可以按单个类别查找条目?就像我在我的数据库中搜索“landscape_designers”并获得所有包含在其中的类别哈希

的条目

我找到了像

这样的东西
Company.where(:'categories.landscape_designers'.gt => 0)

但它不起作用。

提前谢谢!

2 个答案:

答案 0 :(得分:3)

如果categories Hash中的键和值始终相同,则为:

Company.where('categories.landscape_designers' => 'landscape_designers')

应该做的伎俩。如果您只想查看landscape_designers中是否有categories密钥,那么您可以使用$exists

Company.where(:'categories.landscape_designers'.exists => true)
Company.where('categories.landscape_designers' => { :$exists => true })

请注意:

  

$exists 匹配包含存储null值字段的文档。

因此$exists将匹配:categories => { :landscape_designers => nil }。如果你想排除那个病态案例,那么:

Company.where(:'categories.landscape_designers'.ne => nil)
Company.where('categories.landscape_designers' => { :$ne => nil })

无论如何,我认为您的架构存在设计问题。您的categories似乎是一个集合而不是哈希,因此您将字段逻辑类型与其实现混淆。您可以使用Array而不是Hash,让MongoDB的多键负责搜索数组;例如,您的模型会说:

field :categories, :type => Array
# and maybe some uniqueness validation or cleanup

然后你可以将数组视为搜索中的标量:

Company.where(:categories => 'landscape_designers')

然后MongoDB会为你解开数组。

您还可以将一些内容修补到Set

class Set
  def mongoize
    self.to_a
  end

  def self.demongoize(object)
    self.new(object)
  end

  def self.mongoize(object)
    if(object.is_a?(Set))
      object.mongoize
    else
      object
    end
  end

  def self.evolve(object)
    if(object.is_a?(Set))
      object.mongoize
    else
      object
    end
  end
end

然后使用:

field :categories, :type => Set

获取Ruby-land中的自动设置行为和MongoDB中的数组。

答案 1 :(得分:-1)

在公司模型中使用此功能

def method_name
   categories.where("landscape_designers > ?", 0)
end