Mongodb 如何在Mongoid中使用投影?

Mongodb 如何在Mongoid中使用投影?,mongodb,mongoid,Mongodb,Mongoid,我对MongoDB和Mongoid比较陌生。我的MongoDB查询只返回匹配的嵌入记录(使用)如下所示 db.volumes.find({"vol": 1, "chapters.url": "my-chapter"}, {"chapters.$": 1}) 其中一卷包含许多章节。这个查询还利用了我指定的chapters.url字段上的索引 在Mongoid中,上面的等价物是什么?我试过了 Volume.where({vol:1,“chapters.url”=>“我的章节”})。仅(:chapt

我对MongoDB和Mongoid比较陌生。我的MongoDB查询只返回匹配的嵌入记录(使用)如下所示

db.volumes.find({"vol": 1, "chapters.url": "my-chapter"}, {"chapters.$": 1})
其中一卷包含许多章节。这个查询还利用了我指定的
chapters.url
字段上的索引

在Mongoid中,上面的等价物是什么?我试过了

Volume.where({vol:1,“chapters.url”=>“我的章节”})。仅(:chapters)

但它只返回父卷对象及其多个嵌入章节,这与原始MongoDB查询完全返回我要查找的一个章节记录不同。

请查找下面的测试,该测试演示了Mongoid/Moped中最接近的等效项。 Mongoid和轻便摩托车的答案都不“完全”相同。 对于底层的轻便摩托车驾驶员, 查询结果仍将章节子文档包装在父结构中, 因此需要在客户端使用Ruby进行额外的提取。 对于高级ODM Mongoid, 根据定义,查询结果为父模型, 然后#chapters association helper方法遍历到chapters, 第二个#where子句在客户端局部提取。 Mongoid有“拔毛法”, 但它只需要一个简单的字段名, 因此,指定点路径会产生意外结果,并在模型级别返回空

您可以修改测试以满足您的理解。 希望这有帮助

测试/单元/体积测试.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
app/models/volume.rb

class Volume
  include Mongoid::Document
  field :vol, type: Integer
  embeds_many :chapters
end
app/models/chapter.rb

class Chapter
  include Mongoid::Document
  field :url, type: String
  embedded_in :volume
end

谢谢你的详细回答。我已经找到了实现这一目标的第二种(Mongoid)方法。因为我有多个层次的嵌入,所以我继续进行相同的嵌入,因为我最终也会迭代中间对象-
Volume.where(query).first.parts.each
-其中Volume嵌入了很多部分,嵌入了很多章节。这是一个很好的答案。你知道
Volume.where(query).first.chapters.where(“url”=>“我的章节”).first.attributes
是否实际使用了正运算符投影,或者使用了
chapter.url
上的索引?还是它在记忆中做着一切?
class Chapter
  include Mongoid::Document
  field :url, type: String
  embedded_in :volume
end