populate nested array of nested ref

浪子不回头ぞ 提交于 2019-12-20 06:29:14

问题


The structure of the project is

structure

The main file is index.js that is located in the main directory. This one has

'use strict'

var mongoose = require('mongoose');
var app = require('./app');

var port = process.env.port || 3000;

mongoose.connect('mongodb://localhost:27017/changeProducts',(err,res) =>{
    if(err){
        throw err;
    }else{
        console.log("Base de datos funcionando correctamente..");

        app.listen(port, function(){
            console.log('Servidor nodejs corriendo(app.listen)... ');
        });

    }
});

The version of mongoose is 5.0

The app.js is

'use strict'

var express = require('express');
var bodyParser = require('body-parser');

var app = express();

//carga de rutas
//cr
var roleRoutes = require('./routes/cr/role');
var userRoutes = require('./routes/cr/user');
var loginRoutes = require('./routes/cr/login');
//category
var categoryRoutes = require('./routes/cr/category');

//publication
var publicationRoutes = require('./routes/publication/publication');
var offerRoutes = require('./routes/publication/offer');



app.use(bodyParser.urlencoded({
    extended: false
}));

app.use(bodyParser.json());

//configurar cabeceras
app.use((req, res, next)=>{
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Headers', 'X-API-KEY, Origin, X-Requested-With','Content-Type, Accept, Access-Control-Request-Method');
    res.header('Access-Control-Allow-Method', 'GET, POST, OPTIONS, PUT, DELETE');
    res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE');

    next();
});


//rutas base
//cr
app.use('/api', roleRoutes);
app.use('/api', userRoutes);
app.use('/api', loginRoutes);
app.use('/api', categoryRoutes);

//publication
app.use('/api', publicationRoutes);
app.use('/api', offerRoutes);


module.exports = app;

the routes like userRoutes are in the folder routes.

the first route is routes/cr/category.js

'use strict'

var express = require('express');
var CategoryController = require('../../controllers/cr/category');
var api = express.Router();
var middlewareSecurity = require('../../security/middleware');

api.get('/categories', CategoryController.getCategories );

module.exports = api;

the other one is routes/cr/user.js

'use strict'

var express = require('express');
var UserController = require('../../controllers/cr/user');
var api = express.Router();
var middlewareSecurity = require('../../security/middleware');

//api.get('/users/',middlewareSecurity.HasRole("admin,user"), UserController.getUsers );

//actions of user
api.get('/users/', UserController.getUsers);
api.get('/user/:id', UserController.getUser);
api.post('/user', UserController.saveUser);
api.put('/user/:id', UserController.updateUser);
api.delete('/user/:id', UserController.deleteUser);

module.exports = api;

The schemas are in models/cr

the first schema that is located in 'models/category.js' is

'use strict'

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var CategorySchema = Schema({
    name: String,
    subcategories: [{
        name: String
    }]
});

module.exports = mongoose.model('Category',CategorySchema);

The other Schema is UserSchema and it looks like this

 'use strict'

    var mongoose = require('mongoose');
    var Schema = mongoose.Schema;


    var UserSchema = Schema({
        firstName: {
            type: String,
            required: true
        },
        secondName: String,
        lastName: {
            type: String,
            required: true
        },
        email: {
            type: String,
            unique: true,
            required: true
        },
        password: {
            type: String,
            required: true
        },
        status: {
            type: String,
            required: true
        },
        roles: [{
            type: Schema.ObjectId,
            ref: 'Role'
        }],

        publications: [{
            title: {
                type: String,

            },
            description: String,
            status: {
                type: String,

            },
            createdAt: {
                type: Date
            },
            updatedAt: {
                type: Date,
                default: Date.now()
            },

            pictures: [{
                name: String
            }],

            categories: [{
                type: Schema.Types.ObjectId,
                refPath: 'Category'
            }],

            publicationOffers: [{
                idpublication: [{
                    type: Schema.ObjectId,
                    ref: 'User.publications'
                }],
                iduser: {
                    type: Schema.ObjectId,
                    ref: 'User'
                },
                createdAt: {
                    type: Date
                }
            }]
        }]
    });


    module.exports = mongoose.model('User', UserSchema);

I have a plugin called mongooseeder mongooseeder

In order to start I run in terminal

node seeds.

this create some data of category.

after I run

npm start(remember to install dependencies with npm install)

the file controllers/cr/user.js has

'use strict'

var User = require('../../models/cr/user');
var bcrypt = require('bcrypt');
var path = require('path');
var fs = require('fs');

and one of the functions is

   function getUsers(req, res) {

        var find = User.find({}).sort('-firstName');

        find.exec((err, users) => {
            if (err) {
                res.status(500).send({
                    message: "Error en la peticion"
                });
                return;
            }

            if (!users) {
                res.status(404).send({
                    message: "no hay users"
                });
                return;
            }

            User.populate(users, {
                path: 'publications.categories'
            }, (err, users) => {

                if (err) {
                    res.status(500).send({
                        message: "Error en la peticion"
                    });
                    return;
                }

                if (!users) {
                    res.status(404).send({
                        message: "User no encontrado"
                    });
                    return;
                }


                res.status(200).send({
                    users
                });


                // var options = {
                //     path: 'publications.categories',
                //     select: 'subcategories.name'
                // };

                // if (err) {
                //     res.status(200).send({
                //         users
                //     });
                // }
                // User.populate(users, options, function (err, users) {
                //     res.status(200).send({
                //         users
                //     });
                // });

            });
        });
    }

module.exports = {
    getUser,
    getUsers,
    saveUser,
    updateUser,
    deleteUser
}

this method is used by routes/cr/user.js this contains(look the description where is the route and what contains) api.get('/users/', UserController.getUsers);

The link http://localhost:3000/api/users show this

{
    "users": [
        {
            "roles": [
                "5ae4a8b0a7510e3bd80917d5"
            ],
            "publications": [],
            "_id": "5ae79ee4b34bea810861ccc5",
            "firstName": "santiago4",
            "lastName": "torres3",
            "email": "santiago5020g@hotmail.com4",
            "status": "activo",
            "password": "$2b$10$rONv8dlZVOMJ4kU1x4XUmuVeTiyl.B.IVrIIlPDHz.0Yuqh5w05wK",
            "__v": 0
        },
        {
            "roles": [],
            "publications": [
                {
                    "updatedAt": "2018-04-30T03:23:11.921Z",
                    "categories": [
                        "5ae4a8b0a7510e3bd80917db",
                        "5ae4a8b0a7510e3bd80917da"
                    ],
                    "pictures": [],
                    "publicationOffers": [],
                    "_id": "5ae68cbf7cda345ec0b910f3",
                    "title": "publicacio2",
                    "description": "descripcion2",
                    "status": "activo",
                    "createdAt": "2018-04-30T03:25:51.053Z"
                },
                {
                    "updatedAt": "2018-04-30T03:45:14.159Z",
                    "categories": [
                        "5ae4a8b0a7510e3bd80917db"
                    ],
                    "pictures": [],
                    "publicationOffers": [],
                    "_id": "5ae692183670e54b9c529698",
                    "title": "publicacio2",
                    "description": "descripcion2",
                    "status": "activo",
                    "createdAt": "2018-04-30T03:48:40.654Z"
                },
                {
                    "updatedAt": "2018-04-30T04:01:23.131Z",
                    "categories": [
                        "5ae4a8b0a7510e3bd80917db"
                    ],
                    "pictures": [],
                    "publicationOffers": [],
                    "_id": "5ae6956d9e15516ccceb13d8",
                    "title": "publicacio2",
                    "description": "descripcion2",
                    "status": "activo",
                    "createdAt": "2018-04-30T04:02:53.177Z"
                }
            ],
            "_id": "5ae689f9a67a6284f4af4033",
            "firstName": "santiago3",
            "lastName": "torres3",
            "email": "santiago5020g@hotmail.com3",
            "status": "activo",
            "password": "$2b$10$ge1lS.r/eV1nJRkQDi4dn.0AQKpJfI.a5GzBlpsN5trHefVRVjVCS",
            "__v": 0
        },
        {
            "roles": [],
            "publications": [],
            "_id": "5ae689f0a67a6284f4af4032",
            "firstName": "santiago2",
            "lastName": "torres2",
            "email": "santiago5020g@hotmail.com2",
            "status": "activo",
            "password": "$2b$10$HND7lixmr5RT4A/Kz5gv6.it9kmHpauytIHw/UydgTOAwkbNTJf8O",
            "__v": 0
        },
        {
            "roles": [],
            "publications": [],
            "_id": "5ae689e5a67a6284f4af4031",
            "firstName": "santiago1",
            "lastName": "torres1",
            "email": "santiago5020g@hotmail.com1",
            "status": "activo",
            "password": "$2b$10$.sNgBlSerC6f19Hd2.xnzOtpUAd8BB9JXXM5BlGIvr0dUhWOtn5IS",
            "__v": 0
        }
    ]
}

the file controllers/cr/category.js has

'use strict'

var Categories = require('../../models/cr/category');


function getCategories(req, res){

    Categories.find({},(err, categories) =>{
        if(err){
            res.status(500).send({ message: 'Error en la peticion' });
            return;   
        }

        if(!categories){
            res.status(404).send({ message: 'No hay categories' });
            return
        }

        res.status(200).send({ categories });
    });
}


module.exports = {
    getCategories
}

this method is used by routes/cr/category.js this contains(look the description where is the route and what contains)

'use strict'

var express = require('express');
var CategoryController = require('../../controllers/cr/category');
var api = express.Router();
var middlewareSecurity = require('../../security/middleware');

api.get('/categories', CategoryController.getCategories );

module.exports = api;

http://localhost:3000/api/categories will show this json

{
    "categories": [
        {
            "subcategories": [
                {
                    "_id": "5ae4a8b0a7510e3bd80917db",
                    "name": "Decoracion"
                },
                {
                    "_id": "5ae4a8b0a7510e3bd80917da",
                    "name": "Electrodomésticos"
                },
                {
                    "_id": "5ae4a8b0a7510e3bd80917d9",
                    "name": "Cocina"
                },
                {
                    "_id": "5ae4a8b0a7510e3bd80917d8",
                    "name": "Muebles"
                }
            ],
            "_id": "5ae4a8b0a7510e3bd80917d7",
            "name": "Hogar",
            "__v": 0
        },
        {
            "subcategories": [
                {
                    "_id": "5ae4a8b0a7510e3bd80917e0",
                    "name": "Computador escritorio"
                },
                {
                    "_id": "5ae4a8b0a7510e3bd80917df",
                    "name": "Laptop"
                },
                {
                    "_id": "5ae4a8b0a7510e3bd80917de",
                    "name": "Celulares"
                },
                {
                    "_id": "5ae4a8b0a7510e3bd80917dd",
                    "name": "Tablets"
                }
            ],
            "_id": "5ae4a8b0a7510e3bd80917dc",
            "name": "Tecnología",
            "__v": 0
        }
    ]
}

I need to populate categories of UserSchema referencing subcategories of CategorySchema(See Schemas mentioned before). If you see in the file controllers/cr/user.js there is

User.populate(users, {
            path: 'publications.categories'
        }, (err, users) => {....

currently the UserSchema contains this

categories: [{
                type: Schema.Types.ObjectId,
                refPath: 'Category'
            }],

I am trying to do something like this

 categories: [{
                type: Schema.Types.ObjectId,
                refPath: 'Category.subcategories'
            }],

categories is inside of publications(see schemas mentioned before)

I need to get something like this

"publications": [
                {
                    ...
                    "categories": [
                        {
                          "_id": "5ae4a8b0a7510e3bd80917db",
                          "name": "subcategory1"
                        },
                        {
                           "_id": "5ae4a8b0a7510e3bd80917da",
                           "name": "subcategory2"
                        }
                    ]

                },
                {
                    ....
                    "categories": [
                        {
                           "_id": "5ae4a8b0a7510e3bd80917e0",
                           "name": "subcategory1"
                        }
                    ]                
                },
    ]

but it's showing me this in publications of UserSchema

"publications": [
            {
                ...
                "categories": [
                    "5ae4a8b0a7510e3bd80917db",
                    "5ae4a8b0a7510e3bd80917da"
                ]

            },
            {
                ...
                "categories": [
                    "5ae4a8b0a7510e3bd80917e0"
                ]                
            },
]

publications is inisde of UserSchema(see UserSchema mentioned before)

this is the link to download the reporsitory where is the project link of reporsitory

Please help me whith this. I have been searching and trying a lot of things whithout success. I can't find a solution in the documentation, stackoverflow and other websites. Nothing works. I tried to use dinamic references of mongoose and that does not work. I tried to use this. https://github.com/buunguyen/mongoose-deep-populate

And I tried a lot of thing and none of them works. Please Help me!. I am a worry about it.

来源:https://stackoverflow.com/questions/50139312/populate-nested-array-of-nested-ref

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!