按键搜索Mongoid哈希字段

时间:2013-12-16 21:19:57

标签: ruby-on-rails mongodb search mongoid

我认为当我实施它时会很简单,但经过大量搜索,谷歌搜索和扫描文档后,我似乎无法找到答案。

我有一个字段,其中键是id,而值是其他id的数组。例如:

{"52ab84929938c7f966d4f116"=>["52ab84919938c7f966d4ee7d"],
 "52ab84929938c7f966d4f117"=>["52ab84919938c7f966d4ee7d"],
 "52ab84929938c7f966d4f0cc"=>["52ab84919938c7f966d4ee7d", "52ab84929938c7f966d4f13d"],
 "52ab84929938c7f966d4f147"=>["52ab84919938c7f966d4ee7d"]}

这可能更适合图形类型的数据库,但我不熟悉这项技术,并已围绕Mongoid构建了我的应用程序的其余部分。对于另一个复杂的问题,这是我能提出的最简单的解决方案。

所以我的问题是如何搜索记录,例如id:52ab84929938c7f966d4f0cc作为哈希字段中的键?

我尝试像这样做数组样式并返回零结果:

Course.all_in(:skills_available => sk.id)

而且我知道这不起作用,但如果确实如此会很好:

Course.where(:skills_available.key => sk.id)

2 个答案:

答案 0 :(得分:5)

Course.where(:'skills_available.52ab84929938c7f966d4f0cc'.ne => nil)
  • 只有限制才会跳过:{'52ab84929938c7f966d4f0cc' => nil}

答案 1 :(得分:1)

技术上Leszek正确地回答了我的问题。

然而,我很快就意识到我需要能够找到钥匙在一系列钥匙中的所有文件。

因此,作为参考,这是我最终使用的解决方案:

jt = JobType.first
jt_skills = "['#{jt.skills_required.join("','")}']"
m = %Q{
  function() {
    found = false;
    keys = Object.keys(this.skills_available);
    keys.forEach(function(key) {
      if(#{jt_skills}.indexOf(key) > 0) {
        found = true;
      }
    });
    if(found) {
      emit(this._id, keys);
    }
  }
}
r = %Q{
  function(key, values) { }
}
courses = Course.where(:skills_available.ne => {}).map_reduce(m,r).out(inline: true)

第二行将数组转换为可以传递给JS map函数的字符串。 JS map函数检查skills_available散列中的每个键,以查看它是否在skills_required数组中。如果是,则包含该文件。最后,map_reduce仅在有技巧可用的课程上运行。