Rails Mongoid搜索父母至少有一个孩子的元素

时间:2014-07-24 05:45:04

标签: search ruby-on-rails-4 mongoid children

我有一个rails 4应用程序,我有2个对象:商店和书籍(引用1:n关系)。 一家商店有很多书,每本书都属于一家商店。有些商店没有任何书籍。 如何查询至少有1本书的3家最新商店 - 以及3本没有书籍的最新商店?

@stores = Store.order_by(:created_at => 'desc').limit(4).uniq
@books = Book.order_by(:created_at => 'desc').limit(4).uniq

这项工作,但我不知道如何为商店(book.exists?)商店或@books确保每本书属于一个独特的商店。

1 个答案:

答案 0 :(得分:1)

MongoDB中的基本CRUD操作在单个集合上运行, "加入"尚未实现的功能允许它们跨两个集合进行操作。 一旦理解了这一点,您就可以轻松地构建两个可以执行您想要的操作。 鉴于您提供的架构提示,以下内容最为明显。 要做更多的事情,您可能需要考虑嵌入等架构更改。

根据定义,您提供的架构仅允许书籍属于一个(按定义唯一)商店。 您可以从书籍检查中看到这一点,每本书都有一个值store_id。 希望这有助于您理解。

应用程序/模型/ store.rb

class Store
  include Mongoid::Document
  include Mongoid::Timestamps
  field :name, type: String

  has_many :books
end

应用程序/模型/ book.rb

class Book
  include Mongoid::Document
  include Mongoid::Timestamps
  field :title, type: String

  belongs_to :store
end

测试/单元/ store_test.rb

要求' test_helper' 要求' pp'

class StoreTest < ActiveSupport::TestCase
  def setup
    Mongoid.default_session.drop
  end
  test '0. mongoid version' do
    puts "\nMongoid::VERSION:#{Mongoid::VERSION}\nMoped::VERSION:#{Moped::VERSION}"
  end
  test 'store query has book, does not have book' do
    [
        ["Amazon.com", ["Outlander", "Taking It All"]],
        ["Barnes & Noble", ["Big Little Lies"]],
        ["Goodreads", []],
        ["Greenlight Bookstore", []],
        ["Powell's Books", ["Gone Girl", "Dark Skye"]],
        ["Strand Books", []]
    ].each do |store, books|
     store = Store.create(name: store)
     books.each do |title|
       store.books << Book.create(title: title)
     end
     sleep 1
    end
    assert_equal(6, Store.count)
    assert_equal(5, Book.count)
    puts
    store_ids_with_books = Book.distinct(:store_id)
    latest_stores_with_a_book = Store.in(_id: store_ids_with_books).order_by(:created_at => 'desc').limit(3).to_a
    puts "three latest stores with a book:"
    pp latest_stores_with_a_book
    latest_stores_without_a_book = Store.nin(_id: store_ids_with_books).order_by(:created_at => 'desc').limit(3).to_a
    puts "three latest stores without a book:"
    pp latest_stores_without_a_book
    puts "books:"
    pp Book.all.to_a
  end
end

rake test

Run options: 

# Running tests:

[1/2] StoreTest#test_0._mongoid_version
Mongoid::VERSION:3.1.6
Moped::VERSION:1.5.2
[2/2] StoreTest#test_store_query_has_book,_does_not_have_book
three latest stores with a book:
[#<Store _id: 53f257287f11ba75e5000008, created_at: 2014-08-18 19:42:32 UTC, updated_at: 2014-08-18 19:42:32 UTC, name: "Powell's Books">,
 #<Store _id: 53f257257f11ba75e5000004, created_at: 2014-08-18 19:42:29 UTC, updated_at: 2014-08-18 19:42:29 UTC, name: "Barnes & Noble">,
 #<Store _id: 53f257247f11ba75e5000001, created_at: 2014-08-18 19:42:27 UTC, updated_at: 2014-08-18 19:42:27 UTC, name: "Amazon.com">]
three latest stores without a book:
[#<Store _id: 53f257297f11ba75e500000b, created_at: 2014-08-18 19:42:33 UTC, updated_at: 2014-08-18 19:42:33 UTC, name: "Strand Books">,
 #<Store _id: 53f257277f11ba75e5000007, created_at: 2014-08-18 19:42:31 UTC, updated_at: 2014-08-18 19:42:31 UTC, name: "Greenlight Bookstore">,
 #<Store _id: 53f257267f11ba75e5000006, created_at: 2014-08-18 19:42:30 UTC, updated_at: 2014-08-18 19:42:30 UTC, name: "Goodreads">]
books:
[#<Book _id: 53f257247f11ba75e5000002, created_at: 2014-08-18 19:42:28 UTC, updated_at: 2014-08-18 19:42:28 UTC, title: "Outlander", store_id: "53f257247f11ba75e5000001">,
 #<Book _id: 53f257247f11ba75e5000003, created_at: 2014-08-18 19:42:28 UTC, updated_at: 2014-08-18 19:42:28 UTC, title: "Taking It All", store_id: "53f257247f11ba75e5000001">,
 #<Book _id: 53f257257f11ba75e5000005, created_at: 2014-08-18 19:42:29 UTC, updated_at: 2014-08-18 19:42:29 UTC, title: "Big Little Lies", store_id: "53f257257f11ba75e5000004">,
 #<Book _id: 53f257287f11ba75e5000009, created_at: 2014-08-18 19:42:32 UTC, updated_at: 2014-08-18 19:42:32 UTC, title: "Gone Girl", store_id: "53f257287f11ba75e5000008">,
 #<Book _id: 53f257287f11ba75e500000a, created_at: 2014-08-18 19:42:32 UTC, updated_at: 2014-08-18 19:42:32 UTC, title: "Dark Skye", store_id: "53f257287f11ba75e5000008">]
Finished tests in 6.193234s, 0.3229 tests/s, 0.3229 assertions/s.             
2 tests, 2 assertions, 0 failures, 0 errors, 0 skips