在电子商务应用程序中,我有这样的文件:
{ 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.*' 变体进行索引会给我一个错误(复合键太多)。我还怀疑,如果我以这种方式对其进行索引,然后在查询索引中省略其中一个 attrs 将不起作用。
尝试将“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
属性。
在这种情况下如何定义索引?