3

電子商取引アプリケーションには、次のようなドキュメントがあります。

{ category:'A', ..., price:122,
  attr:{ width:6, height:4, hasLCD:true, lcdType:'some text', ..., a36:null }
}

つまり、すべての製品には、さまざまな単純なタイプの多くの属性があります。

ここで、最上位のフィールドといくつかの属性を含む動的クエリで製品をフィルタリングしたいと考えています。例えば:

find({category:'A', price:{$lt:200}, ...,
     'attr.height':{$lt:6}, 'attr.hasLCD':true, 'attr.lcdType':{$in:[...]}, ...})

そして、これを高速に実行したいと思います。

可能なすべての 'attr.*' バリアントでインデックスを作成しようとすると、エラーが発生します (複合キーが多すぎます)。また、そのようにインデックスを付けてから、クエリインデックスの属性の1つを省略しても機能しないと思われます。

全体として「attr」に索引を付けようとしても役に立ちません。

MongoDB でこれをモデル化する適切な方法は何ですか?

アップデート

私はこのアプローチを試しました(ここにも記載されています)。つまり、属性をキーと値のペアの配列として保存します。

attr2: [ {tag:'lcgType', value:'some text'}, ...

そして、次のようにインデックスを付けます。

ensureIndex({ 'attr2.tag':1, 'attr2.value':1 })

そして、次のようにクエリします。

find({attr2:{$all:[
  {$elemMatch:{tag:'bestseller',value:true}},
  {$elemMatch:{tag:'weight',value:{$lte:100}}}
]}})

現在、explain() は、それが使用されていることを示していますが"BtreeCursor attr2.tag_1_attr2.value_1""nscanned" : 31607実行時間全体が実際に増加しています (インデックスなしのシナリオと比較して)。

ここは何かがおかしい。

サブ質問

最も頻繁に照会される属性 (31 未満) をいくつか選択し、それらにインデックスを付けようとするとどうなるでしょうか。それらすべてを単一の複合インデックスに入れると、次のようになります。

ensureIndex({'attr.a1':1, 'attr.a2':1, ...})

ドキュメントによると、このインデックスは、attr.a1属性が欠落しているクエリには使用されません。

この場合、インデックスを定義する方法は?

4

1 に答える 1

2

本当に多くのフィルター、組み合わせ、場合によっては並べ替えを許可する必要がある場合、MongoDB はクエリごとに 1 つのインデックスしか使用しないため、適切ではありませ複合キーはやや柔軟性がなく(サブクエスチョンに答える必要があります)、パフォーマンスを浪費するため、インデックスの数が急激に増加します。

代わりに、必要な機能を備えた ElasticSearch、SolR などの検索データベースを使用してください。$in基本情報を MongoDB に保持したい場合は、検索サーバーが返した ID にa を使用できます (通常は、検索データベースにプライマリ データ ストアの情報を単純にレプリケートすることをお勧めします。同期は双方向で変更されます。これは悪夢です)

于 2013-10-31T11:29:27.130 に答える