電子商取引アプリケーションには、次のようなドキュメントがあります。
{ 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
属性が欠落しているクエリには使用されません。
この場合、インデックスを定義する方法は?