0

我使用 mongomapper 来支持带有 mongodb 的 rails 应用程序,并且需要跨关联查询给定数据集。

例如。

类用户
  包括 Mongoapper::Document

  键:年龄,整数
  许多:人才
结尾
类人才
  包括 Mongoapper::Document

  键:名称,字符串
结尾

现在,如果我想搜索 31 岁的用户,我可以轻松做到

用户.find_by_age(31)。

但是我如何搜索具有杂耍天赋的 31 岁用户?像这样的东西:

User.find_by_age_and_talent(31, “杂耍”)

不必通过 mongomapper ...可以是直接的 mongodb 查询。

4

1 回答 1

3

请注意,您的模型中有拼写错误,Mongomapper 应该是 MongoMapper,抓住这个可以避免一些困惑。

您的模型指定单独的文档,因此您的搜索条件位于单独的文档中。因此,您不能指定跨越文档的单个查询,这相当于连接,并且 MongoDB 中没有连接。正如所写的那样,您被困在对主要结果集进行详尽的辅助查询中。

但是,如果将 Talent 修改为嵌入式文档,则可以在 MongoDB 中进行单个查询,从而在存储和查询方面利用 MongoDB 的优点,而无需 SQL 所需的连接开销。

要运行任一版本,只需将以下模型中的包含更改为 MongoMapper::Document 或 MongoMapper::EmbeddedDocument。测试文件无需修改即可支持两者。

class Talent
  #include MongoMapper::Document
  include MongoMapper::EmbeddedDocument

  key :name, String
end

测试/单元/user_test.rb

require 'test_helper'

class UserTest < ActiveSupport::TestCase
  def setup
    User.delete_all
    Talent.delete_all if Talent.respond_to?(:delete_all)
  end

  test "user talent" do
    if Talent.respond_to?(:create)
      puts "Talent as separate document, not embedded"
      User.create(age: 31, talents: [Talent.create(name: 'juggling')])
      User.create(age: 31, talents: [Talent.create(name: 'singing')])
      User.create(age: 25, talents: [Talent.create(name: 'juggling'), Talent.create(name: 'dancing')])
      assert_equal(3, User.count)
      talent = 'juggling'
      users = User.where(age: 31).select{|user| Talent.where(name: talent).where(user_id: user._id).first}
      assert_equal(1, users.size)
      p users
    else
      puts "Talent as embedded document"
      User.create(age: 31, talents: [Talent.new(name: 'juggling')])
      User.create(age: 31, talents: [Talent.new(name: 'singing')])
      User.create(age: 25, talents: [Talent.new(name: 'juggling'), Talent.new(name: 'dancing')])
      assert_equal(3, User.count)
      talent = 'juggling'
      users = User.where(age: 31).where('talents.name' => talent).to_a
      assert_equal(1, users.size)
      p users
    end
  end
end
于 2012-05-15T20:19:50.183 回答