sql >> Database teknologi >  >> NoSQL >> MongoDB

mongodb få _id som streng i find-forespørgsel

MongoDB 4.0 tilføjer $convert aggregeringsoperator og $toString alias, som giver dig mulighed for at gøre præcis det:

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

En hovedanvendelse ville højst sandsynligt være at bruge _id værdi som en "nøgle" i et 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"] }
              }
            }
          }
        }] 
      ]
    }
  }}
])

Hvilket ville returnere:

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

Hvilket tydeligt viser strengen, ligesom det andet eksempel gør.

Generelt selvom der normalt er en måde at lave "transformer" på markøren, når dokumenter returneres fra serveren. Dette er normalt en god ting, da et ObjectId er en 12-byte binær repræsentation i modsætning til en 24 tegn hex "streng", som tager meget mere plads.

Skallen har en .map() metode

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

Og NodeJS har en Cursor.map() som kan gøre meget det samme:

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

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

Og den samme metode findes også i andre drivere (bare ikke PHP), eller du kan bare gentage markøren og transformere indholdet, som det er mere sandsynligt, at det er bedst at gøre.

Faktisk kan hele markørresultater reduceres til et enkelt objekt med stor lethed ved blot at føje til ethvert markørreturudsagn, når du arbejder i skallen

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

Eller for komplette ES6 JavaScript-understøttende miljøer som nodejs:

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

Virkelig simple ting uden kompleksiteten af, hvad der skal behandles i aggregeringsrammen. Og meget muligt på ethvert sprog på samme måde.



  1. MapReduce med MongoDB virkelig, virkelig langsom (30 timer vs 20 minutter i MySQL for en tilsvarende database)

  2. ClusterControl 1.5-dokumentation - Hvad er nyt

  3. Misbrug cURL til at kommunikere med Redis

  4. Spring data og mongodb - enkel roll back med fjeder inden for @Transactional