【问题标题】:Querying mongodb/mongomapper for data across associations跨关联查询 mongodb/mongomapper 数据
【发布时间】:2023-03-16 13:19:01
【问题描述】:

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

例如。

类用户 包括 Mongoapper::Document 键:年龄,整数 许多:人才 结尾 类人才 包括 Mongoapper::Document 键:名称,字符串 结尾

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

User.find_by_age(31).

但是我如何搜索年龄为 31 岁且具有杂耍天赋的用户? 像这样的:

User.find_by_age_and_talent(31, "juggling")

不一定要通过 mongomapper...可以是直接的 mongodb 查询。

【问题讨论】:

    标签: ruby-on-rails mongodb mongomapper


    【解决方案1】:

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

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

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

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

    class Talent
      #include MongoMapper::Document
      include MongoMapper::EmbeddedDocument
    
      key :name, String
    end
    

    test/unit/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-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多