Estoy aprendiendo MongoDB. He aprendido a trabajar con todos los tipos de datos proporcionados por mongo. Pero estoy atascado en JavaScript. He logrado almacenar la función de JavaScript en el documento. Pero cuando estaba ejecutando esa función, no obtuve nada.
Estoy usando Mongo Shell en la terminal.
Script para insertar función en MongoDB.
db.Test.insertOne({functiontest:function(){return "Hello";}});Después de ejecutar este comando
db.Test.find();tengo esta salida
{ "_id" : ObjectId("618d4096dc79465b4196551b"), "functiontest" : { "code" : "function(){return \"Hello\";}" } }Después de ejecutar este comando
db.Test.find({functiontest:{$type:"javascript"}},{"functiontest.code":1});Obtuve esta salida extraña . Pensé que esta salida me daría una función, pero obtuve esto.
{ "_id" : ObjectId("618d4096dc79465b4196551b") }También intenté ejecutar esta función con canalización, pero eso solo me dio la identificación del objeto.
db.Test.aggregate([{$match:{functiontest:{$type:"javascript"}}},{$project:{"codeMe":"$functiontest.code()"}}]);Javascript almacenado en una colección de usuarios se almacena como cadena.
MongoDB usa internamente BSON para el almacenamiento, consulte https://bsonspec.org/spec.html , que define el contenido del tipo de código javascript como "cadena":
| "\x0D" e_name string código JavaScript
Para demostrarlo, inserté un documento en una nueva colección con:
db.Test.insertOne({_id:"myid",functiontest:function(){return "Hello";}});El del shell bash:
% mongodump -d test -c Test 2021-11-12T01:31:33.817-0800 writing test.Test to dump/test/Test.bson 2021-11-12T01:31:33.818-0800 done dumping test.Test (1 document) % xxd dump/test/Test.bson 00000000: 4100 0000 025f 6964 0005 0000 006d 7969 A...._id.....myi 00000010: 6400 0d66 756e 6374 696f 6e74 6573 7400 d..functiontest. 00000020: 1c00 0000 6675 6e63 7469 6f6e 2829 7b72 ....function(){r 00000030: 6574 7572 6e20 2248 656c 6c6f 223b 7d00 eturn "Hello";}. 00000040: 00Para romper ese maleficio para ese segundo campo:
0d - this identifies the javascript code type 66756e6374696f6e7465737400 null-terminated field name "functiontest" 1c000000 - length = 28 btyrd 66756e6374696f6e28297b72657475726e202248656c6c6f223b7d00 - string 'function(){return "Hello";}' No hay nada especial en esa cadena, aparte de que la introduce 0x0d en lugar de 0x02 .
El REPL que está utilizando en realidad no tiene una forma de mostrar BSON sin procesar, por lo que cuando consulta ese documento, el controlador debe convertirlo a otra forma. JSON no tiene un tipo de datos para el código (por diversión, intente ejecutar JSON.stringify({fun:function(){}}) .
El shell mongo heredado, que usa el controlador C, convertirá ese tipo de código a JSON colocando un objeto con el nombre del campo de code .
El nuevo shell mongosh, que usa el controlador Node.JS, creará una instancia de la clase Code , por lo que el objeto se ve así:
{ _id: 'myid', functiontest: Code("function(){return "Hello";}") } Lo que aún le permite acceder a la cadena con .code :
> db.Test.findOne().functiontest.code function () { return "Hello"; }Ambas representaciones fueron realizadas por el controlador en el lado del cliente, por lo que ninguna existe en el servidor y, por lo tanto, los operadores de proyección no pueden verlas.
Suponiendo que no planea ejecutar su aplicación en el shell mongo, probablemente querrá experimentar con el controlador que realmente planea usar para ver cómo se le devolverá esta cadena.
La conclusión aquí es que el "código" en realidad se almacena como una cadena, y deberá usar el método que prefiera para ejecutar la cadena como código.