我是MongoDB和Mongoid的新手。我的MongoDB查询仅返回匹配的嵌入记录(使用$ projection),如
db.volumes.find({"vol": 1, "chapters.url": "my-chapter"}, {"chapters.$": 1})
其中一个卷嵌入了许多章节。此查询还利用了我指定的chapters.url
字段上的索引。
Mongoid的上述内容相当于什么?我试过了
Volume.where({vol: 1, "chapters.url" => "my-chapter"}).only(:chapters)
但它只返回父卷对象及其多个嵌入式章节,这与原始的MongoDB查询不同,后者只返回我正在寻找的章节记录。
答案 0 :(得分:1)
请查看下面的测试,该测试演示了Mongoid / Moped中最接近的等效项。 Mongoid和Moped的回答都不是“完全”相同。 对于底层驱动程序Moped, 查询结果仍然包含父子结构中包含的子subdoc, 因此在客户端需要在Ruby中进行额外的提取。 对于高级ODM Mongoid, 根据定义,查询结果是根据父模型, 然后#chapters关联助手方法遍历章节, 第二个#where子句在客户端本地提取。 Mongoid有#pluck方法, 但它只需要一个简单的字段名称, 因此,指定一个点路径会产生意外结果,并在模型级别返回空。
您可以修改测试以满足您的理解。 希望这会有所帮助。
测试/单元/ volume_test.rb
require 'test_helper'
require 'pp'
class VolumeTest < ActiveSupport::TestCase
def setup
Volume.delete_all
puts
end
test "project" do
doc = {vol: 1, chapters: [{url: 'my-chapter'}, {url: 'your-chapter'}]}
Volume.create(doc)
assert_equal(1, Volume.count)
query = {"vol" => 1, "chapters.url" => "my-chapter"}
puts "Moped:"
result = Volume.collection.find(query).select("chapters.$" => 1).first['chapters'].first
assert_equal('my-chapter', result['url'])
pp result
puts "Mongoid:"
result = Volume.where(query).first.chapters.where("url" => "my-chapter").first.attributes
assert_equal('my-chapter', result['url'])
pp result
end
test "versions" do
puts "Mongoid version: #{Mongoid::VERSION}\nMoped version: #{Moped::VERSION}"
puts "MongoDB version: #{Volume.collection.database.command({:buildinfo => 1})['version']}"
end
end
$ rake test
Run options:
# Running tests:
[1/2] VolumeTest#test_project
Moped:
{"_id"=>"537274767f11ba1977000002", "url"=>"my-chapter"}
Mongoid:
{"_id"=>"537274767f11ba1977000002", "url"=>"my-chapter"}
[2/2] VolumeTest#test_versions
Mongoid version: 3.1.6
Moped version: 1.5.2
MongoDB version: 2.6.1
Finished tests in 0.063019s, 31.7365 tests/s, 47.6047 assertions/s.
2 tests, 3 assertions, 0 failures, 0 errors, 0 skips
应用程序/模型/ volume.rb
class Volume
include Mongoid::Document
field :vol, type: Integer
embeds_many :chapters
end
应用程序/模型/ chapter.rb
class Chapter
include Mongoid::Document
field :url, type: String
embedded_in :volume
end