【问题标题】:Converting some fields in Mongo from String to Array将 Mongo 中的某些字段从字符串转换为数组
【发布时间】:2016-12-27 06:14:20
【问题描述】:

我有一个文档集合,其中“标签”字段从空格分隔的标签列表切换到单个标签的数组。我想将以前的空格分隔字段更新为像新传入数据一样的数组。

我也遇到了 $type 选择器的问题,因为它将类型操作应用于单个数组元素,这些元素是字符串。所以按类型过滤只会返回所有内容。

如何将每个看起来像第一个示例的文档转换为第二个示例的格式?

{
    "_id" : ObjectId("12345"),
    "tags" : "red blue green white"
}
{
    "_id" : ObjectId("54321"),
    "tags" : [
        "red",
        "orange",
        "black"
    ]
}

【问题讨论】:

  • 很好的问题.. 我试过但无法在 mongodb 中解决它.. 然后我查看了 mongodb jira 及其正在进行的工作.. jira.mongodb.org/browse/SERVER-6773
  • @user641887 jira 已经关闭。但是可以在没有$split 的情况下在 MongoDB 中执行此操作。唯一的问题是性能。

标签: mongodb mapreduce mongodb-query aggregation-framework


【解决方案1】:

我们不能在这里使用$type 运算符来过滤我们的文档,因为我们数组中元素的类型是“字符串”,并且如文档中所述:

当应用于数组时,$type 匹配任何指定 BSON 类型的内部元素。例如,当匹配 $type : 'array' 时,如果该字段具有嵌套数组,则文档将匹配。它不会返回字段本身是数组的结果。

但幸运的是,MongoDB 还提供了 $exists 运算符,可以在此处与数字数组索引一起使用。

现在我们如何更新这些文档?

嗯,从 MongoDB mapReduce(),但首先让我们看看即将发布的 MongoDB 版本中的另一种选择。

从 MongoDB 3.4 开始,我们可以 $project 我们的文档并使用 $split 运算符将我们的字符串拆分为子字符串数组。

请注意,要仅拆分那些为字符串的“标签”,我们需要一个逻辑$condition 处理来仅拆分字符串值。这里的条件是$eq,当字段的$type 等于"string" 时,它的计算结果为true。顺便说一句 $type 这里是 3.4 中的新内容。

最后,我们可以使用$out 管道阶段运算符覆盖旧集合。 但我们需要在$project阶段明确指定包含其他字段

db.collection.aggregate(
     [
        { "$project": { 
            "tags": { 
                "$cond": [ 
                    { "$eq": [ 
                        { "$type": "$tags" }, 
                        "string"
                    ]}, 
                    { "$split": [ "$tags", " " ] }, 
                    "$tags" 
                ] 
            } 
        }},
        { "$out": "collection" }
    ]
)

对于mapReduce,我们需要使用Array.prototype.split() 在我们的map 函数 中发出子字符串数组。我们还需要使用“查询”选项过滤我们的文档。从那里我们需要使用 3.2 中新的 bulkWrite() 方法或现在已弃用的 Bulk() (如果我们在 2.6 或 3.0 上)使用批量操作迭代“结果”数组和 $set“标签”的新值显示here.

db.collection.mapReduce(
    function() { emit(this._id, this.tags.split(" ")); }, 
    function(key, value) {}, 
    { 
        "out": { "inline": 1 }, 
        "query": { 
            "tags.0": { "$exists": false }, 
            "tags": { "$type": 2 }
        }
    }
)['results']

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-04
    相关资源
    最近更新 更多