Ruby on rails 在mongodb/mongomapper中查询跨关联的数据

Ruby on rails 在mongodb/mongomapper中查询跨关联的数据,ruby-on-rails,mongodb,mongomapper,Ruby On Rails,Mongodb,Mongomapper,我使用mongomapper支持一个带有mongodb的rails应用程序,并且需要查询给定数据集的多个关联 例如 class User include Mongomapper::Document key :age, Integer many :talents end 类用户 包含Mongomapper::文档 关键字:年龄,整数 很多:人才 结束 一流人才 包含Mongomapper::文档 关键字:名称、字符串 结束 现在,如果我想搜索一个31岁的用户,我可以很容易地做到 Us

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

例如

class User include Mongomapper::Document key :age, Integer many :talents end 类用户 包含Mongomapper::文档 关键字:年龄,整数 很多:人才 结束 一流人才 包含Mongomapper::文档 关键字:名称、字符串 结束 现在,如果我想搜索一个31岁的用户,我可以很容易地做到

User.find_by_age(31). 用户。按年龄(31)查找。 但是我如何搜索一个31岁的有杂耍天赋的用户呢?? 大概是这样的:

User.find_by_age_and_talent(31, "juggling") 用户。按年龄和天赋查找(31,“杂耍”)
不必通过mongomapper…可以是一个直接的mongodb查询。

请注意,您的模型中有输入错误,mongomapper应该是mongomapper,抓住这一点,省去一些困惑

您的模型指定了单独的文档,因此您的搜索条件位于单独的文档中。因此,您不能指定跨文档的单个查询,这相当于连接,并且MongoDB中没有连接。如前所述,您必须对主要结果集进行彻底的二次查询

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

要运行任一版本,只需将以下模型中的include更改为MongoMapper::Document或MongoMapper::EmbeddedDocument。测试文件支持这两种方式,无需修改

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

  key :name, String
end
测试/单元/用户_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
需要“测试助手”
类UserTesttalent)。to_a
assert_equal(1,users.size)
p用户
结束
结束
结束

请注意,您的模型中有输入错误,Mongomapper应该是Mongomapper,抓住这一点可以省去一些困惑

您的模型指定了单独的文档,因此您的搜索条件位于单独的文档中。因此,您不能指定跨文档的单个查询,这相当于连接,并且MongoDB中没有连接。如前所述,您必须对主要结果集进行彻底的二次查询

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

要运行任一版本,只需将以下模型中的include更改为MongoMapper::Document或MongoMapper::EmbeddedDocument。测试文件支持这两种方式,无需修改

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

  key :name, String
end
测试/单元/用户_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
需要“测试助手”
类UserTesttalent)。to_a
assert_equal(1,users.size)
p用户
结束
结束
结束