感谢您提供示例数据。我的答案将是原始 MQL 解决方案,而不是猫鼬解决方案,因此需要进行一些翻译。
我能够在您的帖子中根据您的 cmets 插入两个文档。我不得不更改两个示例文档之一的 ObjectId,因为您的示例具有相同的主键值并且正在生成重复键异常。
插入样本数据
db.CallerTraces.insert(
{
"_id": ObjectId("6175e7ecc62cff004462d4a6"),
"traces": [
[
ObjectId("6175e7ecc62cff004462d4a4")
]
],
"caller_address": "0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990"
})
db.CallerTraces.insert(
{
"_id": ObjectId("6175e7ecc62cff004462d4a7"),
"traces": [
[
ObjectId("6175e7ecc62cff004462d4a4"),
ObjectId("6175e7ecc62cff004462d4a4")
],
[
ObjectId("6175e7ecc62cff004462d4a4")
]
],
"caller_address": "0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990"
})
如果我想在数组 traces 中查找超过 0 个项目的记录,我可以发出以下命令:
发现不止零的痕迹
db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 0 ] } })
这将返回以下内容:
Enterprise replSet [primary] barrydb> db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 0 ] } })
[
{
_id: ObjectId("6175e7ecc62cff004462d4a6"),
traces: [ [ ObjectId("6175e7ecc62cff004462d4a4") ] ],
caller_address: '0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990'
},
{
_id: ObjectId("6175e7ecc62cff004462d4a7"),
traces: [
[
ObjectId("6175e7ecc62cff004462d4a4"),
ObjectId("6175e7ecc62cff004462d4a4")
],
[ ObjectId("6175e7ecc62cff004462d4a4") ]
],
caller_address: '0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990'
}
]
查找超过 1 条轨迹
如果我想查找多个跟踪,我只需稍微更改查询:
db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 1 ] } })
...这将返回以下结果:
Enterprise replSet [primary] barrydb> db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 1 ] } })
[
{
_id: ObjectId("6175e7ecc62cff004462d4a7"),
traces: [
[
ObjectId("6175e7ecc62cff004462d4a4"),
ObjectId("6175e7ecc62cff004462d4a4")
],
[ ObjectId("6175e7ecc62cff004462d4a4") ]
],
caller_address: '0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990'
}
]
结论
当尝试在查询处理器中评估数组的长度时,我们必须选择使用 $eval 选项,因为 MQL 的语法不考虑您的用例。 $eval 对于不能很好地融入 MQL 框架的事物来说,在某种程度上是一个包罗万象的选项。
更新 #1
OP 引入了额外的要求。而不是看数组的计数,我们必须考虑数组内数组的计数(嵌套内部数组)。由于带有 $expr 的 find() 方法无法评估嵌套数组,我们必须改为使用聚合框架并展开外部数组。此示例将原始表单存储在名为 original 的新字段中,然后在所有评估完成后替换 root。由于展开可能会导致管道中出现重复,因此我们使用 $group 来终止重复。
解决方案
db.CallerTraces.aggregate([
{
$addFields: {
"original._id": "$_id",
"original.traces": "$traces",
"original.caller_address": "$caller_address"
}
},
{
$unwind: "$traces"
},
{
$match: { $expr: { $gt: [ { $size: "$traces" }, 1 ] } }
},
{
$replaceRoot: { newRoot: "$original" }
},
{
$group:
{
_id: "$_id",
traces: { "$first": "$traces" },
caller_address: { "$first": "$caller_address" }
}
}
])