首页 > 解决方案 > 查询系统简介

问题描述

我们正在查询 system.profile 以收集影响某些文档的所有操作(即 DATA.COD:12)

这是 system.profile 文档的片段。

{
        op:"update",
        ns:"db.myCollection",
        command:{
                q: {
                "DATA.COD":12,
                NAME:"PIPPO"
        },
        u:{
                FIELD:"PLUTO"},
        ...
}

我们想要这样的东西

{op:"update", "command.q.DATA.COD":{"$exists":true},ns:"db.myCollection"}

但是名称中的字段不起作用(它搜索子文档)。我们已经尝试过逃生,但到目前为止还没有...

标签: mongodb

解决方案


这不是很漂亮,并且可能不是很有效,但是您应该能够使用$expr和一些聚合操作获得等效的匹配:

db.system.profile.find({op:"update",$expr:{$gt:[{$size:{$filter:{input:{$objectToArray:"$$ROOT.command.q"},cond:{$eq:["$$this.k","DATA.COD"]}}}},0]}})

要打破这一点:

  • op:"update"op- 在球场 上完全匹配
  • $expr- 使用聚合表达式
  • {$objectToArray:"$$ROOT.command.q"}- 将子文档转换command.q为包含单个键值对的文档数组
  • {$eq:["$$this.k","DATA.COD"]}- 检查当前键名是否为“DATA.COD”
  • {$filter:{input: ... , cond: ...}}- 消除输入数组中不符合条件的元素
  • {$size: ...}- 返回数组的大小
  • {$gt:[ ..., 0]}- 确定第一个参数是否大于零

概括:

  • 转换q: {"DATA.COD":12, NAME:"PIPPO"}q:[{k:"DATA.DOC", v:12},{k:"NAME",v:"PIPPO"}]
  • 消除所有不匹配的数组元素k=="DATA.DOC"
  • 如果数组仍然包含任何元素,则匹配文档
  • 对集合中的所有文档重复

推荐阅读