这是我第一次在这里发布信息,希望我的请求能按原样进行删节,但是如果没有,我很抱歉。
我是mongodb的新手,我正在尝试对名为“ builds”的集合执行$ lookup操作,该集合存储了约15.000个文档。 这是存储在此集合中的文档的结构:
{
"_id" : ObjectId("5bc4d54c4d92ca946f67a8f4"),
"branch" : "master",
"build_number" : 11018,
"change" : "390494",
"commit" : "241a12e27baf40aa874687d289a2b5cc02d3d143",
"directory_size" : 621485449,
"duration" : "2035435",
"fingerprints" : {
"commit" : "266e3227d2d68b309998f963bd46653b",
"legacyTreeish" : "e14967681cf356d67b2480704d3ed6bf",
"subtree" : "45fb7898dc1cf0c7ffda3e9e03797953",
"treeish" : "f190542db721000900d33e77090e3dd3"
},
"job" : "MASTER_PROD/UPLANE/L2-PS/BUILD.bbp",
"patchset" : "2",
"pipeline" : "gate",
"project" : "MN/5G/NB/gnb",
"release" : "18A",
"result" : "SUCCESS",
"retries" : 0,
"reused" : 0,
"server" : "es-si-os-ohn-65-5g-ci-common-6d9",
"startTime" : "1531304202954",
"timestamp" : "1531304202953",
"uuid" : "f51420141dc94a03a58bbd28fa35f6c9",
"voting" : true
}
编辑:我正在尝试使用mongo shell执行我的请求。
我正在尝试执行以下请求以查找文档:
将结果键设置为“成功”,并将管道键设置为“检查”。
例如至少存在一个文档,它们具有相同的管道,作业,变更和补丁集,并且结果与“ SUCCESS”不同。
这是我的要求:
db.builds.aggregate(
[
{ $match: { pipeline: "check", result: "SUCCESS" } },
{ $lookup: {
from: "builds",
let: { change: "$change", patchset: "$patchset", result: "$result", job: "$job", pipeline: "$pipeline" },
pipeline: [
{ $match: {
$expr: {
$and:
[
{ $eq: [ "$$change", "$change"]},
{ $eq: [ "$$patchset", "$patchset"]},
{ $eq: [ "$$pipeline", "check" ]},
{ $eq: [ "$$job", "$job" ]},
{ $ne: [ "$$result", "SUCCESS" ]}
]
}
}
}
],
as: "unstables"
}
},
{ $project: { unstables: 1} }
]
)
此请求有两个问题:
当我使用上一个项目操作时需要花费几分钟,而当我不使用它时只需花费几秒钟。对于集合中的以下每个键,我确实有一个索引:更改,补丁集,作业,管道和结果。我想我做错了什么,但我无法确定是什么。
由$ lookup管道阶段填充的“不稳定”数组始终为空。据告诉我有关集合中数据的信息,事实并非如此。我想我对$ lookup操作的使用是错误的,但我不知道为什么。
如果有人能指出正确的方向来解决这个麻烦的请求,我将不胜感激!在此先感谢:)
答案 0 :(得分:0)
您在流水线阶段使用$$犯了一个错误:$$代表“基本”集合,$代表“联合”集合。在管道和结果上使用$ match进行过滤时,
{ $eq: [ "$$change", "$change"]},
{ $eq: [ "$$patchset", "$patchset"]},
{ $eq: [ "$$pipeline", "check" ]}, ===> always true
{ $eq: [ "$$job", "$job" ]},
{ $ne: [ "$$result", "SUCCESS" ]} ===> always false
这是正确的语法:
{ $eq: [ "$$change", "$change"]},
{ $eq: [ "$$patchset", "$patchset"]},
{ $eq: [ "$pipeline", "check" ]}, // or { $eq: [ "$pipeline", "$$pipeline" ]}
{ $eq: [ "$$job", "$job" ]},
{ $ne: [ "$result", "SUCCESS" ]} // or { $ne: [ "$result", "$$result" ]}
但是您可以通过转换您的需求而无需使用$ lookup阶段来达到相同的目的: 您需要使用
构建您可以使用以下方法执行此操作:
db.builds.aggregate([
{
$match: {
pipeline: "check",
}
},
{
$group: {
_id: {
change: "$change",
patchset: "$patchset",
job: "$job",
pipeline: "$pipeline"
},
builds: {
$push: "$$ROOT"
},
resultset: {
$addToSet: "$result"
}
}
},
{
$match: {
$expr: {
$and: [
{
$gt: [
{
$size: "$resultset"
},
1
]
},
{
$in: [
"SUCCESS",
"$resultset"
]
}
]
}
}
}
])
您可以here对其进行测试。希望对您有帮助