使用MongoDB和Mongoose,比方说,我有这个架构:
var componentSchema = mongoose.Schema({
name : String,
price : Number
});
var partSchema = mongoose.Schema({
componentId : { type: Schema.Types.ObjectId, ref: 'Component' },
quantity : Number
});
var robotSchema = mongoose.Schema({
name : String,
type : Number,
parts : [partSchema]
});
每个机器人都需要构建一组组件。
由于机器人可能需要一个以上的组件副本(例如10个螺栓,5个螺钉,1个晶体管......),我们在机器人模型中存储了一个部件阵列,其中每个部分都包含对组件的引用以及附加字段,数量。
现在我有兴趣找到一系列组件的名称(或者,最终给出一个componentIds数组),我可以使用这些类型的组件构建所有机器人(注意组件不包含数量,我只是假设我有无限量的那些组件),由使用给定数组的大多数组件的组件排序。
Robot A: 2 bolts, 2 transistors
Robot B: 10 bolts, 2 capacitors, 3 bars of plutonium
Robot C: 5 bolts, 1 capacitor, 5 transistors
I have [bolts, capacitors, transistors].
Query results:
Robot C
Robot A
(In this order!)
是否可以使用复杂的MongoDB查询?
答案 0 :(得分:2)
不确定。您希望查找机器人文档,以便对于组件列表中的每个组件,信息中该组件的数量小于机器人文档中列出的数量,并且组件列表会耗尽机器人的组件列表。 / p>
// robot docs
{
"name" : "My Fun Robot v3",
"type" : 999,
"parts" : [
{ "_id" : 0, "quantity" : 2 },
{ "_id" : 1, "quantity" : 5 },
{ "_id" : 2, "quantity" : 1 },
{ "_id" : 3, "quantity" : 7 }
]
},
{
"name" : "My Pun Robot v1",
"type" : 222,
"parts" : [
{ "_id" : 4, "quantity" : 3 },
{ "_id" : 1, "quantity" : 4 },
{ "_id" : 2, "quantity" : 8 },
{ "_id" : 6, "quantity" : 1 }
]
},
{
"name" : "My Sun Robot v876",
"type" : 9834,
"parts" : [
{ "_id" : 0, "quantity" : 6 },
{ "_id" : 1, "quantity" : 400 },
{ "_id" : 2, "quantity" : 800 },
{ "_id" : 3, "quantity" : 1000 }
]
},
{
"name" : "My Gun Robot v0",
"type" : 1337,
"parts" : [
{ "_id" : 0, "quantity" : 1 },
{ "_id" : 1, "quantity" : 1 },
{ "_id" : 2, "quantity" : 1 },
]
}
和组件信息
\\ component info
var components = [
{ "_id" : 0, "quantity" : 20 },
{ "_id" : 1, "quantity" : 20 },
{ "_id" : 2, "quantity" : 20 },
{ "_id" : 3, "quantity" : 20 },
{ "_id" : 4, "quantity" : 20 }
]
构建查询:
// for each component, we either need the component not to be required for the robot, or for the robot's quantity required to be less than the quantity we have
var query = {}
var comp_cond = []
components.forEach(function(comp) {
comp_cond.push({ "$or" : [{ "parts" : { "$elemMatch" : { "_id" : comp._id, "quantity" : { "$lte" : comp.quantity } } } }, { "parts._id" : { "$ne" : comp._id } } ]})
})
query["$and"] = comp_cond
// we need to make sure that there's no part in `parts` that's not in the components array
query["parts"] = { "$not" : { "$elemMatch" : { "_id" : { "$nin" : components.map(function(comp) { return comp._id }) } } } }
我不会显示上述示例的实际查询,因为它真的很长。您可以在mongo shell中运行代码并查看它。
> db.robots.find(query, { "_id" : 0, "name" : 1 })
{ "name" : "My Fun Robot v3" }
{ "name" : "My Gun Robot v0" }
我相信这是正确的结果。您应该进行更详尽的测试,以确保它处理组件列表无法与机器人零件列表匹配的所有方式。