如何在MongoDB中按长度查找嵌套的字符串数组元素

tzcvj98z  于 2023-06-29  发布在  Go
关注(0)|答案(2)|浏览(93)

我有一个高度非结构化的动态数据,其中有一个多维字符串数组字段。外部或内部阵列的确切大小事先是未知的,并且可以变化。我想找到所有文档中的任何/所有嵌套数组元素的评估条件我有。所以对于下面的示例文档,我只想匹配它如果任何数组的元素都是ALL,并且字符串长度大于3-在这种情况下是真的。

{
  "_id": "00000000-0000-0007-0000-000000000001",
  "stringArrays": [
    [
      "Hello",
      "World",
      "!"
    ],
    [
      "Fred",
      "Todd"
    ]
  ]
}

第一个数组包含一个小于3的元素“!“,但第二个带名称的数组匹配字符串长度> 3的两个值。因此,总体上满足条件。
到目前为止,我试图找到有关如何做到这一点的信息,但所有的答案要么使用固定的数组索引,我不能或硬正则表达式条件,它工作得更好,但不会在我的所有情况下工作。有时候我还需要查询element.Length $IN [1,3,5,..],这样就可以得到精确的字符串长度值,而不仅仅是$LT或$EQ或$GT。
我唯一的线索可能是使用https://www.mongodb.com/docs/manual/reference/operator/aggregation/strLenCP/#example以某种方式投射额外的字符串长度数据以供稍后查询,但我不知道如何创建一个嵌套的stringArraysLengths,它可能具有相同的结构,但它具有我可以查询的字符串长度。
也许有更好的方法来做到这一点。我对Mongodb比较陌生,希望有更多经验的用户给我一些提示,让我找到正确的方法。谢谢你!

hgqdbh6s

hgqdbh6s1#

下面是一种使用嵌套"$reduce"操作的方法。

db.collection.aggregate([
  {
    "$match": {
      "$expr": {
        "$reduce": {
          "input": "$stringArrays",
          "initialValue": false,
          "in": {
            "$or": [
              "$$value",
              {
                "$reduce": {
                  "input": "$$this",
                  "initialValue": {
                    "$gt": [{"$size": "$$this"}, 0]
                  },
                  "in": {
                    "$and": [
                      "$$value",
                      {"$gt": [{"$strLenCP": "$$this"}, 3]}
                    ]
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
])

mongoplayground.net上试试。

iyr7buue

iyr7buue2#

这将是我的方法:

db.collection.aggregate([
   {
      $set: {
         lengthArray: {
            $map: {
               input: "$stringArrays",
               as: "outer",
               in: {
                  $min: { // get the shortest length
                     $map: {
                        input: "$$outer",
                        in: { $strLenCP: "$$this" } // get length of each sub-strings
                     }
                  }
               }
            }
         }
      }
   },
   {
      $set: {
         overall: { $max: "$lengthArray" }
      }
   },
   { $match: { overall: { $gt: 3 } } },
   //{ $unset: ["lengthArray", "overall"] }
])

Mongo Playground
或者使用$filter删除所有短字符串并检查result是否不为空。

db.collection.aggregate([
   {
      $set: {
         lengthArray: {
            $map: {
               input: "$stringArrays",
               as: "outer",
               in: {
                  $filter: {
                     input: "$$outer",
                     cond: { $gt: [{ $strLenCP: "$$this" }, 3] } // remove all short strings
                  }
               }
            }
         }
      }
   },
   {
      $set: {
         lengthArray: {
            $filter: {
               input: "$lengthArray",
               cond: { $gt: [{ $size: "$$this" }, 0] } // remove all empty arrays
            }
         }
      }
   },
   { $match: { lengthArray: { $ne: [] } } },
   //{ $unset: "lengthArray" }
])

相关问题