Быстрый ответ, что запрос сервера MongoDB работает только на одной коллекции. Нет объединения, которое пересекает коллекции. Вы запрашиваете коллекцию содержимого, но указываете поле, которое находится в коллекции content_types.
Вы можете использовать вложение, чтобы поместить две модели в одну коллекцию, а затем ваш запрос может работать против поля встроенного документа (под).
Я могу предоставить более подробную информацию, если хотите, но, надеюсь, это поможет вам преодолеть нынешнее удивление.
Добавление в соответствии с просьбой, не внедряя:
Важное примечание: доступа к данным из нескольких коллекций потребуется несколько запросов, по меньшей мере, один запрос за коллекцию.
Следующий пример основан на том, что я мог извлечь из вашего сообщения, с изменениями в работе, которые вы хотите использовать для своих методов. В запросе «нет равных» используется знание реализации ассоциации, которое является просто быстрым ответом на данный момент, но структура ссылок довольно очевидна из проверки. Также обратите внимание, что фактические запросы мопедов в MongoDB отображаются в соответствующем журнале Rails.
Я не знаком с подробностями plataformatec/has_scope. У Mongoid есть свои области, которые вы должны исследовать, я готов помочь, когда вы доберетесь туда.
приложение/модели/content_type.rb
class ContentType
include Mongoid::Document
field :name, type: String
has_many :contents
end
приложение/модели/content.rb
class Content
include Mongoid::Document
field :name, type: String
belongs_to :content_type
def self.get_all_content_except_poking_message
Content.where(:name.ne => "no forking, just poking")
end
def self.get_all_content_except_certain_content_type(content_type_name) # 2 queries - one each for ContentType and Content
content_type = ContentType.where(:name => content_type_name).first
Content.where(:content_type_id.ne => content_type.id)
end
end
тест/блок/content_test.Р.Б.
требуют 'test_helper'
class ContentTest < ActiveSupport::TestCase
def setup
Content.delete_all
ContentType.delete_all
end
test "not equal blogs" do
blogs = ContentType.create(:name => "blogs")
tweets = ContentType.create(:name => "tweets")
blogs.contents << Content.create(:name => "no forking, just poking")
tweets.contents << Content.create(:name => "Kilroy was here")
assert_equal 2, ContentType.count
assert_equal 2, Content.count
puts "all content_types: #{ContentType.all.to_a.inspect}"
puts "all contents: #{Content.all.to_a.inspect}"
puts "get_all_content_except_poking_message: #{Content.get_all_content_except_poking_message.to_a.inspect}"
puts "get_all_content_except_certain_content_type(\"blogs\"): #{Content.get_all_content_except_certain_content_type("blogs").to_a.inspect}"
end
end
тест грабли
Run options:
# Running tests:
[1/1] ContentTest#test_not_equal_blogsall content_types: [#<ContentType _id: 51ded9d47f11ba4ec1000001, name: "blogs">, #<ContentType _id: 51ded9d47f11ba4ec1000002, name: "tweets">]
all contents: [#<Content _id: 51ded9d47f11ba4ec1000003, name: "no forking, just poking", content_type_id: "51ded9d47f11ba4ec1000001">, #<Content _id: 51ded9d47f11ba4ec1000004, name: "Kilroy was here", content_type_id: "51ded9d47f11ba4ec1000002">]
get_all_content_except_poking_message: [#<Content _id: 51ded9d47f11ba4ec1000004, name: "Kilroy was here", content_type_id: "51ded9d47f11ba4ec1000002">]
get_all_content_except_certain_content_type("blogs"): [#<Content _id: 51ded9d47f11ba4ec1000004, name: "Kilroy was here", content_type_id: "51ded9d47f11ba4ec1000002">]
Finished tests in 0.046370s, 21.5657 tests/s, 43.1313 assertions/s.
1 tests, 2 assertions, 0 failures, 0 errors, 0 skips
Для этого простого случая, вы можете "упростить" путем отхода от строгой реляционной нормализации, например, просто добавить "content_type_name" в поле «Содержимое» со строковыми значениями, например «блоги».
Но для того, чтобы действительно воспользоваться преимуществами MongoDB, вы не должны стесняться вставлять.
Надеюсь, что это поможет.
Гэри, спасибо за ваш ответ. Если встроенная ассоциация не является опцией, есть ли другой способ издеваться над ассоциацией? Было бы очень полезно, если бы вы предоставили некоторый код, ориентированный на мой сценарий, в качестве примера. :) – Annie
Annie, пример в ответе выше нацелен на ваш сценарий, используя ссылки/ссылки, а не встраивание. Изучите код Content :: get_all_content_except_certain_content_type, который точно отвечает на ваш вопрос с помощью двухэтапной выборки, которая необходима. –