在以下型号中,产品归客户所有。并且不能由其他客户订购。所以我知道,在客户1的订单中,只有客户1拥有的产品。
这里给出一个想法是数据模型的简单版本:
订单:
{
'customer' : 1
'products' : [
{'productId' : 'a'},
{'productId' : 'b'}
]
}
产品:
{
'id' : 'a'
'name' : 'somename'
'customer' : 1
}
我需要找到包含某些产品的订单。我知道产品ID和客户ID。我可以自由地在我的数据库上添加/更改索引。
现在我的问题是。仅在产品ID上添加单个字段索引并仅使用该ID进行查询是否更快。或者我应该使用客户和产品ID寻找复合索引?
我不确定这是否重要,但在我的真实模型中,产品列表实际上是一个对象列表,其中包含产品的数量和dbref。客户也是dbref。
这是一个完整的订单对象:
{
"_id" : 0,
"_class" : "nl.pfa.myprintforce.models.Order",
"orderNumber" : "e35f1fa8-b4c4-4d53-89c9-66abe94a3553",
"status" : "ERROR",
"created" : ISODate("2017-03-30T11:50:50.292Z"),
"finished" : false,
"orderTime" : ISODate("2017-01-12T12:50:50.292Z"),
"expectedDelivery" : ISODate("2017-03-30T11:50:50.292Z"),
"totalItems" : 19,
"orderItems" : [
{
"amount" : 4,
"product" : {
"$ref" : "product",
"$id" : NumberLong(16)
}
},
{
"amount" : 7,
"product" : {
"$ref" : "product",
"$id" : NumberLong(26)
}
},
{
"amount" : 8,
"product" : {
"$ref" : "product",
"$id" : NumberLong(7)
}
}
],
"stateList" : [
{
"timestamp" : ISODate("2017-03-28T11:50:50.074Z"),
"status" : "NEW",
"message" : ""
},
{
"timestamp" : ISODate("2017-03-29T11:50:50.075Z"),
"status" : "IN_PRODUCTION",
"message" : ""
},
{
"timestamp" : ISODate("2017-03-30T11:50:50.075Z"),
"status" : "ERROR",
"message" : "Something went wrong"
}
],
"customer" : {
"$ref" : "customer",
"$id" : ObjectId("58dcf11a71571a24c475c044")
}
}
答案 0 :(得分:0)
当我有以下索引时:
1: {"customer" : 1, "orderItems.product" : 1}
2: {"orderItems.product" : 1}
两个计数查询(我使用count来强制查找没有网络传输的所有文档):
a: db.getCollection('order').find({
'orderItems.product' : DBRef('product',113)
}).count()
b: db.getCollection('order').find({
'customer' : DBRef('customer',ObjectId("58de009671571a07540a51d5")),
'orderItems.product' : DBRef('product',113)
}).count()
在一组200k上以~0.007秒的相同时间运行。 当我为不同的客户(和不同的产品)添加1000k记录时,它根本不会影响时间。
扩展说明显示:
查询1只使用索引2。 查询2使用索引2但也考虑索引1.这里可能使用索引交集吗?
因为如果我删除索引1,结果是:
查询a:0.007秒 查询b:0.035秒(5倍长!)
所以我的结论是,通过正确的索引,两种方法的工作速度都很快。但是,如果你不需要复合指数,那只会浪费空间和空间。写速度。
所以:单字段索引更好在我的情况下。