简体   繁体   中英

Querying mongoose to perform a join

I have 2 collections setup as below, Dates and Streets .

What I would like to achieve is to, query Streets by a param StreetName and look that up to find it's unique ID and then query the other collection by that ID to pull back all the dates that match.

My route is set up to /wasteDate/:StreetName . Here's what I have:

model.js

var DateSchema = new Schema({
  date: {
    type: Date
  },   
  street_id: {
    type: String,
  }
});

var StreetSchema = new Schema({
  name: {
    type: String
  }
});

routes.js

module.exports = function(app) {
    var wasteCollections = require('../controllers/wasteController'); 
    app.route('/wasteDate/:streetName')
        .get(wasteCollections.get_dates_by_street_name);
}; 

controller.js

var mongoose = require('mongoose'),
  ColDate = mongoose.model('Dates'),
  that = this,
  Street = mongoose.model('Streets');

(...)

exports.manual_get_dates_by_street = function (id) {
  var wasteDates = ColDate.find({ street_id: id }).lean();
  return wasteDates;
};

exports.get_dates_by_street_name = function (req, res) {
  Street.find({
    name: req.params.streetName
  }, function(err, street) {
    var query;
    var theStreetId = street[0].id;
    if (err) res.send(err);
    query = that.manual_get_dates_by_street(theStreetId);
    res.json(query);
  });
};

at the moment i'm getting a circular reference error on the JSON.

I don't think I'm doing it the right way and think I may need to amend my schema?

Any help appreciated

I never used it but I think mongoose-models may resolve your problem. https://github.com/SportZing/mongoose-models

Another possible approach is to put the second query function as a callback of the first.

You can either use (1) find twice or (2) aggregation .

Here's the first way:

exports.manual_get_dates_by_street = function (id, callback) {
    // you are dealing with asynchronous operations, so you have to wait for the callback
    // to execute before you can get the data
    ColDate.find({ street_id: id }).lean().exec(callback);
};

exports.get_dates_by_street_name = function (req, res) {
    // you are expecting one result, so use findOne instead of find
    Street.findOne({ name: req.params.streetName }, function (err, street) {
        // make sure you handle errors properly such as stopping execution of
        // the next lines or else you may get unexpected errors
        if (err) 
            return res.send(err);

        // we pass a callback that will be executed once results (or an error) are found
        that.manual_get_dates_by_street(street._id, function (err, dates) {
            res.json({ dates: dates });
        });
    });
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM