MongoDB中数组中字符串字段值的长度

5

如何获取嵌套在另一个字段中的字段的字符长度?它是在一个数组中。例如:

{
    "_id" : ObjectId("687e1db"),
    "content" : {
        "ods" : "1102223000241",
        "startDate" : ISODate("2017-05-11T12:00:00Z"),
        "classes" : [
            {
              "driveNumber" : "9999078900007091",
              "number" : "00107605829357",
              "sId" : "0000000005009593"
            }
        ],
         "user" : "SoftLogic",
    },
    "level" : 2
}

我想在content.classes.number字段中获取长度大于16个字符的样本。 在进行请求时,我是参考MongoDB中字符串字段值长度的指引操作的。 要么这个请求不适用于这种情况,要么我做错了什么。
db.Basis.find({
    "content.classes.number": { "$exists": true }, 
    "$expr": { "$gt": [ { "$strLenCP": "$content.classes.number" }, 16 ] }})

我遇到了错误:https://gyazo.com/d2849406d36364de94d6ea89eff1c2b6

我尝试了不止这些选项。

更新:mongo版本为3.4.3。


2
错误的意思就是它所说的那样,即 "classes" 实际上是一个数组,因此任何字段路径表达式,如 $content.classes.number,也会产生与匹配值相对应的数组。您的问题仅显示单个数组成员,因此不清楚在结构中使用数组是不正确的,它应该是单数形式,还是您实际上希望这是一个数组,并且确实可以有多个成员 - Neil Lunn
3
如果实际上应该是一个数组,那么$expr应该是"$expr": { "$anyElementTrue": { "$map": { "input": "$content.classes.number", "in": { "$gt": [ { "$strLenCP": "$$this" }, 16 ] } } } }。这基本上与"$where": "this.content.classes.some(e => e.number.length > 16)"作为替代的$where表达式是相同的。虽然语法更加简洁,但$expr应该比$where处理速度更快。 - Neil Lunn
@NeilLunn 谢谢!不只是一个项目。所以你肯定是对的,答案是:"$expr": { "$anyElementTrue": { "$map": { "input": "$content.classes.number", "in": { "$gt": [ { "$strLenCP": "$$this" }, 16 ] } } } }。它出现在版本3.6.9中。但事实证明,在版本3.4.3上安装它是必要的,并且在这里 https://gyazo.com/8031da7305191d3bdfd02ca87abafdd5。 - Сома Тха
为何您不能升级您的版本?新版本总是更好的,所以最好使用升级版。 - Ashh
是的,我同意。这个版本对我来说不是本地的,而是在生产中。需要理解是否有符合这些条件的数据。 - Сома Тха
因此,$expr文档确实告诉您“自版本3.6起新功能”,这就是为什么上面显示的两种情况,因为如果您的MongoDB版本不是3.6或更高版本,那么您想要的是$where表达式。请注意,从本帖发布之日起不到5个月的时间里,3.4版本将不再获得官方支持。 - Neil Lunn
1个回答

3

content.classes.number是一个数组字段而不是字符串,这就是为什么你的查询无法工作的原因。

在这里的一个解决方案是使用$arrayElemAt运算符,但不知道你想检查哪个元素。但例如,我这里取第0个元素。

db.Basis.find({
  "content.classes.number": { "$exists": true }, 
  "$expr": { "$gt": [{ "$strLenCP": { "$arrayElemAt": ["$content.classes.number", 0] }}, 16 ] }
})

2
有点冒险假设数组只有一个元素。我知道问题只显示了一个,但应该假定 Array 意味着 "一个数组" 并相应地处理。另一方面,如果问题明确要求 "第一个数组元素", 那么 $arrayElemAt 就可以了。但很可能不是实际情况。有运算符可以处理所有可能的数组元素。请参见问题的注释。 - Neil Lunn
1
@NeilLunn 嗯,我知道原帖的问题有点不清楚。这就是为什么我写了“但是不知道你想要检查哪个元素”,并等待他的回复。**:-)** 而你的评论我认为应该是答案,因为它似乎正是原帖所需的。 - Ashh
@Anthony Winzlet NeilLunn 绝对是正确的。但不幸的是,这个问题在版本3.4.3中仍然存在 https://gyazo.com/8031da7305191d3bdfd02ca87abafdd5 - Сома Тха
@СомаТх 是的,Neil Lunn永远不会错。我正在等待您的回复。我会根据您的需求更新我的答案,但您需要更清楚明确。 - Ashh
@Anthony Winzlet,你的回答真的很有帮助,但它并没有涉及数组中的所有情况。同时,生产环境中的版本是3.4.3。 - Сома Тха
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接