假设我们有两个集合:
devices
:该集合中的对象具有(除其他外)字段 name
(字符串)和 cards
(数组);该数组中的每个部分都有字段 model
和 slot
。卡片不是另一个集合,它只是一些嵌套数据。interfaces
:该集合中的对象具有(除其他外)字段 name
和 owner
。额外信息:
cards
,我只对 slot
是数字的那些感兴趣part
的 device
,在另一个集合中有一个 interface
对象,其中 owner
字段的值为 {{原因中的 name
的 1}} 且名称为 device
(字符 's' + 该部分的插槽 + 'p1')我的工作是创建一个查询以生成所有这些设备中所有现有卡的摘要,每个条目都包含来自 s[slot]p1
集合的信息。我还需要能够对查询进行参数化(以防我只对具有特定名称的特定设备感兴趣,仅对卡片的特定型号等感兴趣)
到目前为止,我有这个:
interfaces
查询有效并且速度非常快,但我有一个问题:
有什么办法可以避免第二个mongo_client.devices.aggregate([
# Retrieve all the devices having the cards field
{
"$match": {
# "name": "<device-name>",
"cards": {
"$exists": "true"
}
}
},
# Group current content with every cards object
{
"$unwind": "$cards"
},
# Only take the ones having "slot" a number
{
"$match": {
"cards.slot": {
"$regex": "^\d+$"
}
}
},
# Retrieve the device's interfaces
{
"$lookup": {
"from": "interfaces",
"let": {
"owner": "$name",
},
"as": "interfaces",
"pipeline": [{
"$match": {
"$expr": {
"$eq": ["$owner", "$$owner"]
},
},
}]
}
},
{
"$unwind": "$interfaces"
},
{
"$match": {
"$expr": {
"$eq": ["$interfaces.name", {
"$concat": ["s", "$cards.slot", "p1"]
}]
}
}
},
# Build the final object
{
"$project": {
# Card related fields
"slot": "$cards.slot",
"model": "$cards.model",
# Device related fields
"device_name": "$name",
# Fields from interfaces
"interface_field_x": "$interfaces.interface_field_x",
"interface_field_y": "$interfaces.interface_field_y",
}
},
])
?如果每个 $unwind
有 50-150 个 device
对象,其中 interface
是该设备的名称,我觉得我正在减慢它的速度。每个设备都有一个名为 owner
的唯一接口。如何以更好的方式获得该特定对象?我试图在 s[slot]p1
甚至 $eq
或 $match
内部的 $lookup
中使用两个 $regex
表达式,但我无法使用外部 {{1 }} 字段,即使我把它放在 $regexMatch
中。
如果我想参数化我的查询以在需要时过滤数据,您会添加匹配表达式作为中间步骤还是只在最后过滤?
欢迎对查询进行任何其他改进。我也对如何证明错误很感兴趣(如果错误地缺少 slot
或找不到 let
接口。
谢谢!
答案 0 :(得分:1)
您的问题缺少查询的示例数据,但是:
查询中展开的次数应与您想要在结果集中的对象相对应:
为了匹配所需的条件,不需要展开。