Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 删除以“名称”开头的所有字段;";_Javascript_Mongodb_Mongodb Query - Fatal编程技术网

Javascript 删除以“名称”开头的所有字段;";

Javascript 删除以“名称”开头的所有字段;";,javascript,mongodb,mongodb-query,Javascript,Mongodb,Mongodb Query,集合中的示例文档: {“teamAlpha”:{},“teamBeta”:{},“leader_name”:“leader”} 对于这样的文档,我想删除所有以“team”开头的字段。因此,预期的结果是 {leader_name:“leader”} 我目前正在使用一个函数: db.teamList.find().forEach( function(document) { for(var k in document) { if (k.startsWit

集合中的示例文档:

{“teamAlpha”:{},“teamBeta”:{},“leader_name”:“leader”}

对于这样的文档,我想删除所有以
“team”
开头的字段。因此,预期的结果是

{leader_name:“leader”}

我目前正在使用一个函数:

db.teamList.find().forEach(
    function(document) {
        for(var k in document) {
            if (k.startsWith('team')) {
                delete document[k];
            }
        }
        db.teamList.save(document);
    }
);
我想知道是否有更好的方法解决这个问题。

最好是事先确定所有可能的密钥,然后发布一个更新来删除所有密钥。根据可用的MongoDB版本,将有不同的方法

MongoDB 3.4:$objectToArray
.aggregate()
语句通过
$objectToArray
将文档中的字段转换为数组,然后仅应用于返回“key”的前四个字母与字符串匹配的字段
“team”
。然后使用和进行处理,以生成匹配字段的“唯一列表”

后续指令仅将游标中返回的列表处理为单个对象,如:

{
    "teamBeta" : "",
    "teamAlpha" : ""
}
然后将其传递给以从所有文档中删除这些字段

早期版本:mapReduce 相同的基本问题,其中唯一的区别是,where不存在一种方法,我们只需使用调用来应用于所有匹配的文档。这就是新的API调用实际上所做的一切

除了这些选择之外 当然,仅仅为了删除字段而迭代所有文档是不明智的,因此上述任何一种方法都是“首选”方法。唯一可能的失败是构造键的“不同列表”实际上超过了16MB BSON限制。这是非常极端的,但根据实际数据,这是可能的

因此,本质上有“两个扩展”自然适用于这些技术:

  • 将“光标”与
    .aggregate()一起使用

    var fields = [];
    
    db.teamList.aggregate([
      { "$project": {
        "_id": 0,
        "fields": {
          "$map": {
            "input": {
              "$filter": {
                "input": { "$objectToArray": "$$ROOT" },
                "as": "d",
                "cond": { "$eq": [{ "$substrCP": [ "$$d.k", 0, 4 ] }, "team" ] }
              }
            },
            "as": "f",
            "in": "$$f.k"
          }
        }
      }},
      { "$unwind": "$fields" },
      { "$group": { "_id": "$fields" } }
    ]).forEach( d => {
      fields.push(d._id);
    
      if ( fields.length >= 2000 ) {
        db.teamList.updateMany({},
          { "$unset": 
            fields.reduce((acc,curr) => Object.assign(acc,{ [curr]: "" }),{})
          }
        );
      }
    });
    
    if ( fields.length > 0 ) {
      db.teamList.updateMany({},
        { "$unset": 
          fields.reduce((acc,curr) => Object.assign(acc,{ [curr]: "" }),{})
        }
      );
    }
    
    db.teamList.mapReduce(
      function() {
        Object.keys(this).filter( k => /^team/.test(k) )
          .forEach( k => emit(k,1) );
      },
      function() {},
      { "out": { "replace": "tempoutput" } }
    );
    
    db.tempoutput.find({},{ "_id": 1 }).forEach(d => {
      fields.push(d._id);
    
      if ( fields.length >= 2000 ) {
        db.teamList.update({},
          { "$unset": 
            fields.reduce((acc,curr) => Object.assign(acc,{ [curr]: "" }),{})
          },
          { "multi": true }
        );
      }
    });
    
    if ( fields.length > 0 ) {
      db.teamList.update({},
        { "$unset": 
          fields.reduce((acc,curr) => Object.assign(acc,{ [curr]: "" }),{})
        },
        { "multi": true }
      );
    }
    
    这实际上是将“游标”上处理的字段数“成批”为2000个,作为请求,“应”保持在16MB BSON限制之下

  • 使用带有
    mapReduce()的临时集合

    var fields = [];
    
    db.teamList.aggregate([
      { "$project": {
        "_id": 0,
        "fields": {
          "$map": {
            "input": {
              "$filter": {
                "input": { "$objectToArray": "$$ROOT" },
                "as": "d",
                "cond": { "$eq": [{ "$substrCP": [ "$$d.k", 0, 4 ] }, "team" ] }
              }
            },
            "as": "f",
            "in": "$$f.k"
          }
        }
      }},
      { "$unwind": "$fields" },
      { "$group": { "_id": "$fields" } }
    ]).forEach( d => {
      fields.push(d._id);
    
      if ( fields.length >= 2000 ) {
        db.teamList.updateMany({},
          { "$unset": 
            fields.reduce((acc,curr) => Object.assign(acc,{ [curr]: "" }),{})
          }
        );
      }
    });
    
    if ( fields.length > 0 ) {
      db.teamList.updateMany({},
        { "$unset": 
          fields.reduce((acc,curr) => Object.assign(acc,{ [curr]: "" }),{})
        }
      );
    }
    
    db.teamList.mapReduce(
      function() {
        Object.keys(this).filter( k => /^team/.test(k) )
          .forEach( k => emit(k,1) );
      },
      function() {},
      { "out": { "replace": "tempoutput" } }
    );
    
    db.tempoutput.find({},{ "_id": 1 }).forEach(d => {
      fields.push(d._id);
    
      if ( fields.length >= 2000 ) {
        db.teamList.update({},
          { "$unset": 
            fields.reduce((acc,curr) => Object.assign(acc,{ [curr]: "" }),{})
          },
          { "multi": true }
        );
      }
    });
    
    if ( fields.length > 0 ) {
      db.teamList.update({},
        { "$unset": 
          fields.reduce((acc,curr) => Object.assign(acc,{ [curr]: "" }),{})
        },
        { "multi": true }
      );
    }
    
    在本质上也是相同的过程的情况下,除了
    mapReduce
    无法输出到“游标”之外,您需要输出到仅包含“不同字段名”的临时集合,然后从该集合中迭代游标,以便以相同的“批处理”方式进行处理

  • 与类似的初始方法一样,与迭代整个集合并单独调整每个文档相比,这些方法的性能更高。一般来说,这是不必要的,因为任何“不同列表”实际导致单个更新请求超过16MB的可能性确实是极端的。但这将再次成为处理这种极端情况的“首选”方式

    一般的 当然,如果您只知道所有字段名,而不需要通过检查集合来计算它们,那么只需使用已知名称编写语句即可:

    db.teamList.update({},{ "$unset": { "teamBeta": "", "teamAlpha": "" } },{ "multi": true })
    
    这是非常有效的,因为所有其他语句都在计算这些名称应该适合您。

    最好是事先确定所有可能的键,然后发布一个更新以删除所有键。根据可用的MongoDB版本,将有不同的方法

    MongoDB 3.4:$objectToArray
    .aggregate()
    语句通过
    $objectToArray
    将文档中的字段转换为数组,然后仅应用于返回“key”的前四个字母与字符串匹配的字段
    “team”
    。然后使用和进行处理,以生成匹配字段的“唯一列表”

    后续指令仅将游标中返回的列表处理为单个对象,如:

    {
        "teamBeta" : "",
        "teamAlpha" : ""
    }
    
    然后将其传递给以从所有文档中删除这些字段

    早期版本:mapReduce 相同的基本问题,其中唯一的区别是,where不存在一种方法,我们只需使用调用来应用于所有匹配的文档。这就是新的API调用实际上所做的一切

    除了这些选择之外 当然,仅仅为了删除字段而迭代所有文档是不明智的,因此上述任何一种方法都是“首选”方法。唯一可能的失败是构造键的“不同列表”实际上超过了16MB BSON限制。这是非常极端的,但根据实际数据,这是可能的

    因此,本质上有“两个扩展”自然适用于这些技术:

  • 将“光标”与
    .aggregate()一起使用

    var fields = [];
    
    db.teamList.aggregate([
      { "$project": {
        "_id": 0,
        "fields": {
          "$map": {
            "input": {
              "$filter": {
                "input": { "$objectToArray": "$$ROOT" },
                "as": "d",
                "cond": { "$eq": [{ "$substrCP": [ "$$d.k", 0, 4 ] }, "team" ] }
              }
            },
            "as": "f",
            "in": "$$f.k"
          }
        }
      }},
      { "$unwind": "$fields" },
      { "$group": { "_id": "$fields" } }
    ]).forEach( d => {
      fields.push(d._id);
    
      if ( fields.length >= 2000 ) {
        db.teamList.updateMany({},
          { "$unset": 
            fields.reduce((acc,curr) => Object.assign(acc,{ [curr]: "" }),{})
          }
        );
      }
    });
    
    if ( fields.length > 0 ) {
      db.teamList.updateMany({},
        { "$unset": 
          fields.reduce((acc,curr) => Object.assign(acc,{ [curr]: "" }),{})
        }
      );
    }
    
    db.teamList.mapReduce(
      function() {
        Object.keys(this).filter( k => /^team/.test(k) )
          .forEach( k => emit(k,1) );
      },
      function() {},
      { "out": { "replace": "tempoutput" } }
    );
    
    db.tempoutput.find({},{ "_id": 1 }).forEach(d => {
      fields.push(d._id);
    
      if ( fields.length >= 2000 ) {
        db.teamList.update({},
          { "$unset": 
            fields.reduce((acc,curr) => Object.assign(acc,{ [curr]: "" }),{})
          },
          { "multi": true }
        );
      }
    });
    
    if ( fields.length > 0 ) {
      db.teamList.update({},
        { "$unset": 
          fields.reduce((acc,curr) => Object.assign(acc,{ [curr]: "" }),{})
        },
        { "multi": true }
      );
    }
    
    这实际上是将“游标”上处理的字段数“成批”为2000个,作为请求,“应”保持在16MB BSON限制之下

  • 使用带有
    mapReduce()的临时集合

    var fields = [];
    
    db.teamList.aggregate([
      { "$project": {
        "_id": 0,
        "fields": {
          "$map": {
            "input": {
              "$filter": {
                "input": { "$objectToArray": "$$ROOT" },
                "as": "d",
                "cond": { "$eq": [{ "$substrCP": [ "$$d.k", 0, 4 ] }, "team" ] }
              }
            },
            "as": "f",
            "in": "$$f.k"
          }
        }
      }},
      { "$unwind": "$fields" },
      { "$group": { "_id": "$fields" } }
    ]).forEach( d => {
      fields.push(d._id);
    
      if ( fields.length >= 2000 ) {
        db.teamList.updateMany({},
          { "$unset": 
            fields.reduce((acc,curr) => Object.assign(acc,{ [curr]: "" }),{})
          }
        );
      }
    });
    
    if ( fields.length > 0 ) {
      db.teamList.updateMany({},
        { "$unset": 
          fields.reduce((acc,curr) => Object.assign(acc,{ [curr]: "" }),{})
        }
      );
    }
    
    db.teamList.mapReduce(
      function() {
        Object.keys(this).filter( k => /^team/.test(k) )
          .forEach( k => emit(k,1) );
      },
      function() {},
      { "out": { "replace": "tempoutput" } }
    );
    
    db.tempoutput.find({},{ "_id": 1 }).forEach(d => {
      fields.push(d._id);
    
      if ( fields.length >= 2000 ) {
        db.teamList.update({},
          { "$unset": 
            fields.reduce((acc,curr) => Object.assign(acc,{ [curr]: "" }),{})
          },
          { "multi": true }
        );
      }
    });
    
    if ( fields.length > 0 ) {
      db.teamList.update({},
        { "$unset": 
          fields.reduce((acc,curr) => Object.assign(acc,{ [curr]: "" }),{})
        },
        { "multi": true }
      );
    }
    
    在本质上也是相同的过程的情况下,除了
    mapReduce
    无法输出到“游标”之外,您需要输出到仅包含“不同字段名”的临时集合,然后从该集合中迭代游标,以便以相同的“批处理”方式进行处理

  • 与类似的初始方法一样,与迭代整个集合并单独调整每个文档相比,这些方法的性能更高。一般来说,这是不必要的,因为任何“不同列表”实际导致单个更新请求超过16MB的可能性确实是极端的。但这将再次成为处理这种极端情况的“首选”方式

    一般的 当然,如果您只知道所有字段名,而不需要通过检查集合来计算它们,那么只需使用know编写语句即可