设查询的大小嵌套阵列

0

的问题

我有以下模式:

Schema({
caller_address: {
    type: String,
    required: true,
},
traces: [[{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Call',
}]]

});

我想只检索的对象,有迹线的电话量大于一定数目。 换句话说,尺寸至少一套系列的痕迹,应该被超过一个指定的数量。 我试图使用$elemMatch美元的大小,但没有成功。 现在,我有这样的代码:

CallerTraces.find({ 'traces' : { $elemMatch: { $size : { $gt: minTraceSize } }}})

在minTraceSize是一个int.

可能你们帮帮我吗? 我真感激!

arrays mongodb nested
2021-11-23 20:27:28
1

最好的答案

0

谢谢你的样本数据。 我的答案将是一个原MMS的解决方案,而不是一个猫鼬解决方案,因此,一些翻译将是必需的。

我能插入两个文件的基础上你的评论在你的岗位。 我不得不改变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"
})

如果我想找到记录具有超过0项目中的阵列 traces 我可以问题如下:

发现零余痕迹

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 选择作为语法MMS不考虑你的使用情况。 的 $eval 是有点赶-所有的选择做的事情没有很好地适应在MMS框架。

更新#1 OP引入了额外的要求。 而不是看该计阵列,我们必须考虑计数的阵阵列内(嵌套内部阵列)。 由于找到()方法与美元的expr无法评估嵌套阵列,我们必须,而不是使用聚合框架,并放松了外阵列。 这个例子中储存的原始形成在一个新的领域被称为 original 然后代替了根之后的所有评价是完整的。 由于退可能导致重复的管道我们最终确定与美元的组抑制重复。

解决方案

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" }
        }
    }
])
2021-11-24 21:42:44

你好,谢谢你对你的快速反应! 但是我还没有问题...我想要得到的痕迹的大小在第二级别的嵌套。 所以,如果我有:{"_id":ObjectId("6175e7ecc62cff004462d4a7"),"踪迹":[[ObjectId("6175e7ecc62cff004462d4a4")、ObjectId("6175e7ecc62cff004462d4a4")]],"caller_address":"0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990"})此目的应该返回的时候我设置2minTraceSize变量。
Bruno Medeiros

@BrunoMedeiros-请看到更新的在我的职务。
barrypicker

它的工作! 谢谢你这么多! =)
Bruno Medeiros

其他语言

此页面有其他语言版本

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................