且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

mongodb在查找查询中将_id作为字符串获取

更新时间:2023-02-24 09:33:45

MongoDB 4.0添加了 别名,您可以执行此操作:

MongoDB 4.0 adds the $convert aggregation operator and the $toString alias which allows you to do exactly that:

db.getCollection('example').aggregate([
  { "$match": { "example":1 } },
  { "$project": { "_id": { "$toString": "$_id" } } }
])

最主要的用法是将_id值用作文档中的键".

A main usage would most likely be though to use the _id value as a "key" in a document.

db.getCollection('example').insertOne({ "a": 1, "b": 2 })

db.getCollection('example').aggregate([
  { "$replaceRoot": {
    "newRoot": {
      "$arrayToObject": [
        [{ 
          "k": { "$toString": "$_id" },
          "v": {
            "$arrayToObject": {
              "$filter": {
                "input": { "$objectToArray": "$$ROOT" },
                "cond": { "$ne": ["$$this.k", "_id"] }
              }
            }
          }
        }] 
      ]
    }
  }}
])

哪个会返回:

{ 
  "5b06973e7f859c325db150fd" : { "a" : 1, "b" : 2 }
}

与其他示例一样,它清楚地显示了字符串.

Which clearly shows the string, as does the other example.

通常,通常有一种方法可以在从服务器返回文档时对光标进行转换".这通常是一件好事,因为ObjectId是12字节的二进制表示形式,而不是24字符的十六进制字符串",后者占用更多空间.

Generally though there is usually a way to do "transforms" on the cursor as documents are returned from the server. This is usually a good thing since an ObjectId is a 12-byte binary representation as opposed to a 24 character hex "string" which takes a lot more space.

该外壳具有.map()方法

db.getCollection('example').find().map(d => Object.assign(d, { _id: d._id.valueOf() }) )

NodeJS的Cursor.map()可以完成很多相同的事情:

And NodeJS has a Cursor.map() which can do much the same thing:

let cursor = db.collection('example').find()
    .map(( _id, ...d }) => ({ _id: _id.toString(), ...d }));

while ( await cursor.hasNext() ) {
  let doc = cursor.next();
  // do something
})

其他驱动程序中也存在相同的方法(只是PHP没有),或者您可以迭代游标并转换内容,这是***的做法.

And the same method exists in other drivers as well ( just not PHP ), or you can just iterate the cursor and transform the content as is more likely the best thing to do.

实际上,在shell中工作时,只需将其添加到任何游标返回语句中,就可以轻松地将整个游标结果简化为单个对象

In fact, whole cursor results can be reduced into a single object with great ease by simply adding to any cursor returning statement, when working in the shell

.toArray().reduce((o,e) => { 
  var _id = e._id;
  delete e._id;
  return Object.assign(o, { [_id]: e })
},{ })

或者对于完整的ES6 JavaScript支持环境,例如nodejs:

Or for full ES6 JavaScript supporting environments like nodejs:

.toArray().reduce((o,({ _id, ...e })) =>  ({ ...o, [_id]: e }),{ })

真正简单的东西,没有聚合框架中需要处理的内容的复杂性.而且,通过几乎相同的方式,在任何一种语言中都非常有可能.

Really simple stuff without the complexity of what needs to process in the aggregation framework. And very possible in any language by much the same means.