2

I'm trying to make a query between two collections in mongodb using node js.

I have these two collection in the db:

Trip

{               
    "_id":ObjectId("55a922531e35772c1b17d4a0"),
    "name":"trip_name",
    "waypoints":[
        "4c828999d8086dcb03877752",
        "4dd2ae657d8b4c6585f1a6fd",
        "4c59c3e4f346c928a8634dca"
    ],
    "line_points":[
        [
            42.850937,
            13.569256
        ],
        [
            42.85109,
            13.569377
        ],
        [
            42.851131,
            13.569225
        ]
    ],
    "time":"00:10:23",
    "distance":6.622,
    "hashKey":"object:8207"
};

Poi

{  
      "_id":"4c828999d8086dcb03877752",
      "type":"Feature",
      "geometry":{  
         "type":"Point",
         "coordinates":[  
            13.575249910354614,
            42.85484995890166
         ]
      },
      "properties":{  
         "title":"Lorenz Cafè",
         "id":"4c828999d8086dcb03877752",
         "poi-type":1,
         "category":"ristorazione",
         "subCategory":"Café",
         "categoryIds":"4bf58dd8d48988d16d941735",
         "marker-color":"#FF7519",
         "marker-size":"small",
         "marker-symbol":"restaurant",
         "indirizzo":"Piazza del Popolo, 5",
         "citta":"Ascoli Piceno",
         "regione":"Marche"
      }

Through the route, I do I query according to the id that step and I would like that the query I would restore a json like this:

Result i want

{"_id":"55a922531e35772c1b17d4a0","name":"trip_name","waypoints":[{"4c828999d8086dcb03877752":{"title":"Lorenz Cafè","id":"4c828999d8086dcb03877752","category":"ristorazione","position":{"lat":42.85484995890166,"lng":13.575249910354614}}},{"4dd2ae657d8b4c6585f1a6fd":{"title":"Ottica Di Ferdinando","id":"4dd2ae657d8b4c6585f1a6fd","category":"negozi","position":{"lat":42.85485741498569,"lng":13.57675423240643}}},{"4c59c3e4f346c928a8634dca":{"title":"Leopoldus Ristorante","id":"4c59c3e4f346c928a8634dca","category":"ristorazione","position":{"lat":42.85648980743132,"lng":13.575512766838072}}}],"line_points":[[42.850937,13.569256],[42.85109,13.569377],[42.851131,13.569225]],"time":"00:10:23","distance":6.622}

I implemented this route :

/*
TRIP BY ID
 */
var j=0;
router.get('/:id', function(req, res) {
    db = req.db;
    var idString=req.params.id;
    var objId = new ObjectID(idString);
    var collection2=db.get('poilist');
    var collection = db.get('trip');

    collection.find({"_id": objId},{},function(e,docs){
        var trip=docs[0];
        var poi=[];
        var wp=trip.waypoints;

        for(var i=0; i< wp.length; i++)
        {
            collection2.find({"properties.id": wp[i]},function(e,docs2){
                poi[j]={
                        "title" : docs2[0].properties.title,
                        "id": docs2[0].properties.id,
                        "category": docs2[0].properties.category,
                        "position": {"lat":docs2[0].geometry.coordinates[1], "lng":docs2[0].geometry.coordinates[0]}
                    };
                    var id = wp[j];
                    wp[j]= {};
                    wp[j][id]=poi[j];
                    if(j==wp.length-1){
                        console.log('emit '+j);
                        emitter.emit('attesa' + j);
                    }else{
                        j++;
                    }

            });
        }
        emitter.once('attesa'+ (trip.waypoints.length-1) ,function() {
            j=0;
            console.log('once');

            res.json(trip);
        });
    });
});

This route works but if you were to make multiple calls simultaneously, no longer work.

I have an idea: count the number of requests and go to double check if the id of the place is in this trip but it seems very expensive. I would like to know a more practical method for making queries with multiple collections in mongo. Thanks in advance

0

2 Answers 2

6

first i recommend you use mongoose. Before all you must prepare your Models, for example:

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

var personSchema = Schema({
  _id     : Number,
  name    : String,
  age     : Number,
  stories : [{ type: Schema.Types.ObjectId, ref: 'Story' }]
});

var storySchema = Schema({
  _creator : { type: Number, ref: 'Person' },
  title    : String,
  fans     : [{ type: Number, ref: 'Person' }]
});

var Story  = mongoose.model('Story', storySchema);
var Person = mongoose.model('Person', personSchema);

and after this when you want "join" you most use next method:

Story.find().populate("fans");

For moar http://mongoosejs.com/docs/populate.html

Sign up to request clarification or add additional context in comments.

3 Comments

Excuse me, since I do not know well mongoose, what are its advantages over the library that I used?
Mongoose enables you to give your database a structure (schema) and run more advanced queries. check out mongoosejs.com/docs/guide.html for more help
Can we filter Story.find().populate("fans"); based on person.name like in sql select * from a JOIN b on a.a = b.b where b.some like "%filtertext%"
1

Just get the basic JSON data on first request

{ "_id":ObjectId("55a922531e35772c1b17d4a0"), "name":"trip_name", "waypoints":[ "4c828999d8086dcb03877752", "4dd2ae657d8b4c6585f1a6fd", "4c59c3e4f346c928a8634dca" ] }

Then call other API which gets data of waypoints using async calls and promise and once promises are resolved, merge them.

1 Comment

i don't understand what you say, sorry

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.