mongodb 当配置数据库触发器时,数据库触发器匹配表达式中的My $or选择器在嵌套的第二级不起作用

gojuced7  于 2023-05-28  发布在  Go
关注(0)|答案(2)|浏览(110)

更新:我使用“$match expression”来描述这一点,但实际上我并没有使用$match运算符。根据文档,选择器应该符合$match的语法,尽管$match关键字在实际表达式中显然不是必需的。
更新2:在实际集合中,outerField表示messagefieldA表示fansNofieldB表示sharedNo。所以outerField.fieldA代表message.fansNoouterField.fieldB代表message.sharedNo。这是触发器触发时updateDescription字段的字符串化表示(即当我只在match表达式中指定updateDescription.updatedField时):

"updateDescription: {\"removedFields\":[],\"updatedFields\":{\"someOtherField\":310,\"message.fansNo\":1,\"updatedAt\":\"2020-06-22T13:29:08.829Z\"}}"

================================================================

原文

所以我不明白为什么当我在match表达式中指定message.fansNomessage.sharedNo时,它无法触发。
我在更新集合时设置了一个database trigger,但我无法让$match表达式过滤导致触发器触发的更改事件。我希望只有当两个嵌套字段中的一个或两个都存在时才触发触发器,比如fieldAfieldB。这两个字段嵌套在一个对象中,对象是每个文档中字段的值。就像这样:

// CollectionA schema
{
  _id: ...,
  outerField: {
    fieldA: 1 // or any number
    fieldB: 2 // or any number
  },
  ...
}

我尝试使用下面的$match表达式,但触发器不触发:

{
  "$or": [
    {
      "updateDescription.updatedFields.outerField.fieldA": {"$exists":true}
    },
    {
      "updateDescription.updatedFields.outerField.fieldB":{"$exists":true}
    }
  ]
}

如果我删除outerField.<field>,它就可以工作。即:

{
  "$or": [
    {
      "updateDescription.updatedFields": {"$exists":true}
    },
    {
      "updateDescription.updatedFields":{"$exists":true}
    }
  ]
}

当然,这对我来说没有用,因为触发器会在任何更新时触发。
我会提供一个演示,但我不知道如何创建一个样本,有数据库触发器配置。任何帮助将不胜感激,谢谢!

jpfvwuh4

jpfvwuh41#

因此,我可以通过更改查询来监视同时更新但没有嵌套的字段,从而解决这个问题。我认为检查嵌套字段的问题在于ChangeEventupdateDescription属性不包含已经更改的实际嵌套对象;相反,它包含改变的点表示。因此,如果你在我的帖子中查看Update 2,你会看到updatedFields有这个值:{\"someOtherField\":310,\"message.fansNo\":1...而不是{\"someOtherField\":310,\"message\":{\"fansNo\":1...。通过在$match查询中使用message.fansNo,Mongo将查找以下对象形状:{\"message\":{\"fansNo\":1...,在本例中不匹配。这里的一个“真实的”解决方案可能是在我的匹配表达式中转义message.fansNo中的.,但我无法使其工作(请参阅this thread)。
因此,对我有效的“解决方案”实际上只是适用于我特定用例的解决方案:碰巧someOtherField总是与message.fansNo沿着更新,而someOtherField没有嵌套。所以我可以匹配someOtherField而不用担心嵌套。基本上,这个匹配表达式给了我想要的结果:

{
  "$or": [
    {
      "updateDescription.updatedFields.someOtherField": {"$exists":true}
    },
    {
      "updateDescription.updatedFields.someOtherField":{"$exists":true}
    }
  ]
}

希望这对别人有帮助!

uinbv5nw

uinbv5nw2#

{
  "$expr": {
    "$ne": [{
      "$size": {
        "$filter": {
          "input": { "$objectToArray": "$updateDescription.updatedFields" },
          "cond": { "$regexMatch": { "input": "$$this.k", "regex": "message\\.fansNo" } }
        }
      }
    }, 0]
  }
}

需要注意的是,MongoDB将包含点的字段解释为嵌套对象。因此,无法使用常规查询语法直接搜索带点的字段。为了克服这一限制并搜索带点的字段,所提供的查询使用$objectToArray运算符将updatedFields对象转换为键值对数组。通过这样做,可以访问和处理各个字段。随后的操作,例如$filter$regexMatch,被应用于数组元素,使得能够搜索包含点的字段。
这种方法允许查询克服MongoDB将点作为嵌套对象的默认解释,并有效地匹配所需的字段message.fansNo,即使它包含点。

相关问题