Monggomapper:使用关联模型的键对数据进行排序

时间:2012-05-20 11:48:50

标签: sorting mongodb mongomapper model-associations

这基本上是一项简单的任务,但我找不到如何使用属于其关联的键在Mongomapper Model中执行排序/订单数据的方法。

假设我有两个模型:

class Product 
 include MongoMapper::Document

 key :name, String
 key :product_category_id, ObjectId

 belongs_to :product_category
end

class ProductCategory
 include MongoMapper::Document

 key :name, String, :required => true, :unique => true
end

我想做的只是简单地从“产品”中获取按“产品类别名称”排序的数据。我已经尝试过了:

Product.where(:name => /#{@keyword}/i).sort("product_category.name".to_sym)

但没有工作,还有许多其他方式来回报错误:(...

有人可以帮我解决这个问题吗?非常感谢...

谢谢

此致 罗尼

1 个答案:

答案 0 :(得分:1)

如您的问题所述,Product和ProductCategory映射到MongoDB中的单独集合。 因此,您无法进行SQL连接,排序,选择和唯一。对于普通查询,MongoDB不会访问多个集合。 您可以在本地内存中对产品进行排序,但这需要同时获取产品及其相关的product_categories。

Products.all.sort{|a, b| a.product_category.name <=> b.product_category.name}

但是,您可以利用嵌入,以便数据集中在一个集合中,因此MongoDB可以轻松对其进行排序。

class Product
  include MongoMapper::Document

  key :name, String
  one :product_category
end

class ProductCategory
  include MongoMapper::EmbeddedDocument

  key :name, String
end

请注意,ProductCategory是EmbeddedDocument。 下面的测试显示了'product_category.name'的MongoMapper排序子句。 希望这有助于您的理解和进步。

测试/单元/ product_test.rb

require 'test_helper'

class ProductTest < ActiveSupport::TestCase
  def setup
    Product.delete_all
  end

  test "association sort" do
    Product.create(name: 'Act of Valor', product_category: ProductCategory.new(name: 'movie'))
    Product.create(name: 'Oliver Twist', product_category: ProductCategory.new(name: 'book'))
    assert_equal(2, Product.count)

    products_by_db_order = Product.all.to_a
    assert_equal(['Act of Valor', 'Oliver Twist'], products_by_db_order.map(&:name))
    p products_by_db_order.map(&:name)

    products_by_category_order = Product.sort('product_category.name').to_a
    assert_equal(['Oliver Twist', 'Act of Valor'], products_by_category_order.map(&:name))
    p products_by_category_order.map(&:name)
  end
end

输出

Run options: --name=test_association_sort

# Running tests:

["Act of Valor", "Oliver Twist"]
["Oliver Twist", "Act of Valor"]
.

Finished tests in 0.042368s, 23.6027 tests/s, 70.8082 assertions/s.

1 tests, 3 assertions, 0 failures, 0 errors, 0 skips