sql >> Database >  >> NoSQL >> MongoDB

mongodb get _id als string in zoekquery

MongoDB 4.0 voegt de $convert . toe aggregatie-operator en de $toString alias waarmee u precies dat kunt doen:

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

Een hoofdgebruik is waarschijnlijk het gebruik van de _id waarde als een "sleutel" in een 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"] }
              }
            }
          }
        }] 
      ]
    }
  }}
])

Wat zou terugkeren:

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

Wat duidelijk de string laat zien, net als het andere voorbeeld.

Over het algemeen is er echter meestal een manier om "transformaties" op de cursor uit te voeren als documenten worden geretourneerd door de server. Dit is meestal een goede zaak aangezien een ObjectId is een 12-byte binaire representatie in tegenstelling tot een 24 karakters hex "string" die veel meer ruimte in beslag neemt.

De shell heeft een .map() methode

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

En NodeJS heeft een Cursor.map() die ongeveer hetzelfde kunnen doen:

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

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

En dezelfde methode bestaat ook in andere stuurprogramma's (alleen niet in PHP), of je kunt gewoon de cursor herhalen en de inhoud transformeren, wat waarschijnlijk het beste is om te doen.

In feite kunnen hele cursorresultaten met groot gemak worden teruggebracht tot een enkel object door simpelweg toe te voegen aan een willekeurige cursorretouropdracht, wanneer u in de shell werkt

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

Of voor volledige ES6 JavaScript-ondersteunende omgevingen zoals nodejs:

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

Echt eenvoudige dingen zonder de complexiteit van wat er in het aggregatieraamwerk moet worden verwerkt. En heel goed mogelijk in elke taal op vrijwel dezelfde manier.



  1. Verschil tussen op documenten gebaseerde en op sleutel/waarde gebaseerde databases?

  2. Een reeds uitgevoerde taak annuleren in Python RQ?

  3. XFS vs EXT4 – MongoDB-prestaties vergelijken op AWS EC2

  4. Redis lua-script werkt niet