0

次のドキュメント定義があります(ルビーです)

class Block
  include Mongoid::Document

  field :index, type: Integer  # index 0,1,..  
  field :codes, type: Array    #[A, B, C,... ]

  embedded_in :Video
end

class Video
  include Mongoid::Document

  field :name, type: String
  embeds_many :blocks, :order => :index.asc
end

プロパティに一致するクエリを実行したいのですvideo.blocks.codesが、埋め込みドキュメントの配列プロパティです。主に2種類のクエリを実行したい:

  • null 以外/空でないcodes配列を持つブロックはいくつ存在しますか?
  • コード配列が特定の位置の特定の文字列と一致するブロックはいくつありますか?

一致させようとしているデータの例を次に示します。

video#1
blocks: [{index: 1, codes:["a","g","c"]}, {index: 2, codes: [] }]

video#2
blocks: [{index: 1, codes:["x","b","d", "e"]}, {index: 2, codes: ["x","b"] }]

たとえば、空でないコード配列のないブロックの数(答えは3 つのブロック) と、2 番目の位置 (インデックス 1) にあるブロックの数b(答えは2 つ) を知りたいです。

私はmongoidドライバーを使用しているので、理想的にはクエリでドライバーを使用しますが、プレーンモンゴは問題ありません。ありがとう!

4

2 に答える 2

0

私見Blockは、追加の属性を持つ別のコレクションである必要がありますnum_codes(埋め込まれておらず、コードはテストされていません)。

class Video
    include Mongoid::Document
    has_many :blocks
end

class Block
    include Mongoid::Document
    belongs_to :video
    field :index
    field :num_codes
    field :codes

    # warning pseudo code ahead:
    before_save :update_codes
    def update_codes
       # set num_codes to length of codes
       # delete all codes belonging to this block and recreate them
    end
end

空のブロックを照会するには: Blocks.where(num_codes : 0). これにより、要件 1 が解決されます。

要件 2 について: 私の知る限り、MongoDB では、配列内の特定のインデックスで値をクエリすることはできません (ただし、これについては間違っている可能性があります)。繰り返しますが、私の提案は別のコレクションを作成することです(コードはテストされていません):

class Code
   include Mongoid::Document
   belongs_to :block
   field :position
   field :value
end

Code.where(position : 3, value : 'x')

したがって、ビデオの保存には、サイズにもよりますが、約 2-n 回の挿入が必要になりますcodes。ただし、コレクションはインデックス可能 ( [:num_codes]forBlocksおよび[:position, :value]for Code) であり、大規模なコレクションであっても、妥当なクエリ パフォーマンスが得られるはずです。それが役立つことを願っています。

于 2013-06-10T22:53:29.173 に答える