sql >> Databasteknik >  >> NoSQL >> MongoDB

mongodb få _id som sträng i sökfrågan

MongoDB 4.0 lägger till $convert aggregeringsoperator och $toString alias som låter dig göra exakt det:

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

En huvudanvändning skulle med största sannolikhet vara att använda _id värde som en "nyckel" i ett dokument.

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"] }
              }
            }
          }
        }] 
      ]
    }
  }}
])

Vilket skulle returnera:

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

Vilket tydligt visar strängen, liksom det andra exemplet.

Generellt men det finns vanligtvis ett sätt att göra "transformers" på markören när dokument returneras från servern. Detta är vanligtvis en bra sak eftersom ett ObjectId är en 12-byte binär representation i motsats till en 24 teckens hex "sträng" som tar mycket mer utrymme.

Skalet har en .map() metod

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

Och NodeJS har en Cursor.map() som kan göra ungefär samma sak:

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

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

Och samma metod finns i andra drivrutiner också (bara inte PHP), eller så kan du bara iterera markören och omvandla innehållet, vilket är mer troligt det bästa du kan göra.

Faktum är att hela markörresultat kan reduceras till ett enda objekt med stor lätthet genom att helt enkelt lägga till ett markörreturerande uttalande när man arbetar i skalet

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

Eller för fullständiga ES6 JavaScript-stödjande miljöer som nodejs:

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

Riktigt enkla saker utan komplexiteten i vad som behöver bearbetas i aggregeringsramverket. Och mycket möjligt på vilket språk som helst på ungefär samma sätt.



  1. MongoDB $concat

  2. Online Apache HBase Backups med CopyTable

  3. (nod:3341) DeprecationWarning:Mongoose:mpromise

  4. Heroku Redis - GUI och minnesoptimering