sql >> Databáze >  >> NoSQL >> MongoDB

mongodb získá _id jako řetězec ve vyhledávacím dotazu

MongoDB 4.0 přidává $convert agregační operátor a $toString alias, který vám umožňuje přesně to:

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

Hlavním použitím by s největší pravděpodobností bylo použití _id hodnotu jako "klíč" v dokumentu.

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

Což by se vrátilo:

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

Což jasně ukazuje řetězec, stejně jako druhý příklad.

Obecně však obvykle existuje způsob, jak provést "transformace" na kurzoru, protože dokumenty jsou vráceny ze serveru. To je obvykle dobrá věc, protože ObjectId je 12bajtová binární reprezentace na rozdíl od 24znakového hex "řetězce", který zabírá mnohem více místa.

Shell má .map() metoda

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

A NodeJS má Cursor.map() který může dělat totéž:

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

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

A stejná metoda existuje i v jiných ovladačích (jen ne v PHP), nebo můžete jen iterovat kurzor a transformovat obsah, jak je pravděpodobně nejlepší.

Ve skutečnosti lze celé výsledky kurzoru s velkou lehkostí zredukovat na jeden objekt jednoduchým přidáním do libovolného příkazu pro návrat kurzoru při práci v shellu

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

Nebo pro prostředí s plnou podporou JavaScriptu ES6, jako je nodejs:

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

Opravdu jednoduché věci bez složitosti toho, co je potřeba zpracovat v agregačním rámci. A je to velmi možné v jakémkoli jazyce téměř stejnými prostředky.



  1. Porovnání memcache, redis a ehcache jako distribuovaného cachovacího rámce

  2. Připojte laravel jenssegers k mongodb atlas clusteru

  3. Jaký je nejjednodušší způsob, jak najít největší objekty v Redis?

  4. Jak používat šifrování k ochraně dat MongoDB