Mongoose 多个同步查找以重用对象 ID [英] Mongoose multiple synchronous find to reuse object ID

查看:68
本文介绍了Mongoose 多个同步查找以重用对象 ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的模型在每个对象之间有很多关系,当我想搜索一些数据时,我必须找到前一个对象,这让我写了很多回调.

My models has lot of relationship between each object and when I want to search some data I have to find the previous object and it makes me to write lot of callback.

我有 4 个模型:

  1. 公司:只有一个字段,即公司名称字段
  2. 地理位置:两个字段,纬度/经度
  3. 办公室:姓名、地址和两个 ObjectID:地理位置对象 ID 和公司对象 ID
  4. 用户:电子邮件、密码等...以及 Office 对象 ID
  1. Company: Just one field, the company name field
  2. Geolocation: Two field, latitude / longitude
  3. Office: name, address and two ObjectID : Geolocation Object ID and Company Object ID
  4. User: email, password etc... and the Office Object ID

然后我需要通过纬度/经度获取最近的用户及其信息(姓名、办公室名称、公司、名称等).这是地狱的结果回调.

Then I need to get the nearest users with their informations ( name, office name, company, name etc... ) by latitude / longitude. And here is the result callback from hell.

    // Find all Geolocation
    Geolocation.find({}, function(err, geolocations) {
        if (err) throw err;

        var array = [];

        // Loop on geolocations object
        Async.each(geolocations, function(origin, callback){

            var myJson = {"latitude":43.686978, "longitude":7.201922};

            // Calculate distance between two points
            var geo = geolib.getDistance(
                {latitude: origin.latitude, longitude: origin.longitude},
                {latitude: myJson.latitude, longitude: myJson.longitude}
            );

            // Find the office with the current geolocation object ID
            Office.findOne({ geolocation: origin._id}, function(err, office){
                if (err) throw err;

                // Find the company with the current office object ID
                Company.findOne({ _id: office.company }, function(err, company){
                    if (err) throw err;

                    // Find the user with the current office object ID
                    User.findOne({office: office._id}, function(err, user){
                        if (err) throw err;

                        array.push({
                            user: user.firstname+' '+user.lastname,
                            office: office.name,
                            company: company.name,
                            distance: geo
                        });

                        callback();
                    });
                });
            });

        }, function(err) {
            array.sort(function (a, b) {
                return a.distance - b.distance;
            });

            for (var i = 0; i < array.length; i++){
                console.log(array[i])
            }
        });

    });

我正在使用 async 但我不知道这是否是了解何时的好方法循环结束,如果 each() 方法是最合适的.

I'm using async but I don't know if it's the good way to know when the loop is finished and if the each() method is the most most appropriate.

如您所见,我必须进行大量查找才能获取对象 ID,然后再次查找以获取用户的所有信息.

As you can see I have to make lot of find to get the Object ID and find again to get all informations by users.

你有没有让我的代码更简洁的想法?或者我不应该在我的模型中使用对象 ID?

Do you have an idea to make my code cleaner ? Or maybe I shouldn't use object ID in my models ?

推荐答案

您可以将每个 findOne 函数包装到 promise 中,并使用 Babel 中的 await.在这种情况下,您的代码可能如下所示:

You can wrap each findOne function into the promise and use await from Babel. In this case, your code may look like this:

let office = await new Promise((resolve, reject) => {
    Office.findOne({ geolocation: origin._id}, function(err, office){
        if (err) reject(err)
        resolve(office)
});

let company = await new Promise((resolve, reject) => {
    Company.findOne({ _id: office.company }, function(err, company){
        if (err) reject(err)
        resolve(company)
});
... and so on

或者,也许您想了解 MongoDB 中的人口:http://mongoosejs.com/docs/populate.html

Or, maybe you want to read about population in MongoDB: http://mongoosejs.com/docs/populate.html

这篇关于Mongoose 多个同步查找以重用对象 ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆