Mongoose: Mongoose query won't return any result while same query in MongoDB does

Created on 11 Aug 2016  路  6Comments  路  Source: Automattic/mongoose

I'm trying to build an application using MEAN but now I'm stuck when trying to find linestrings intersecting on another one given its name.

For instance, given the following image, poly1 and poly2 should have intersections while poly3 does not.

fc

Let's suppose poly1 has the following coordinates and the following JSON:

{ 
  "_id" : ObjectId("57ab2107505ab11b1bd8422e"), 
  "name" : "poly1", 
  "updated_at" : ISODate("2016-08-10T12:41:43.789+0000"), 
  "created_at" : ISODate("2016-08-10T12:41:43.780+0000"), 
  "geo" : {
      "coordinates" : [ [14.59, 24.847], [28.477, 15.961] ], 
      "type" : "LineString"
  }, 
  "__v" : NumberInt(0)
}

When I run the query on MongoChef I find both poly1 and poly2 and I do not find poly3 like I want:

{
    geo :{
        $geoIntersects:{
            $geometry :{
                type: "LineString" ,
                coordinates: [ [14.59, 24.847], [28.477, 15.961] ]
            }
        }
    }
}

While, when I run the query on Mongoose given a Polyline Id/name it does not work

//Given
var linestringById = Linestrings.find({name : lineName});
var linestrings    = Linestrings.find({});    

//Works
query = linestrings.where({ geo : { $geoIntersects : 
                    { $geometry : 
                       { type : 'LineString', 
                         coordinates : [ [27.528, 25.006], [14.063, 15.591] ]
                        } 
                     } } });

//Does not work
query = linestrings.where({ geo : { $geoIntersects : 
                   { $geometry : 
                     { type : 'LineString', coordinates : linestringById }}}});

This is the Schema for LineStrings:

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

// Creates a LineString Schema.
var linestrings = new Schema({
    name: {type: String, required : true},
    geo : {
        type : {type: String, default: "LineString"},
                coordinates : Array
    },
    created_at: {type: Date, default: Date.now},
    updated_at: {type: Date, default: Date.now}
});

// Sets the created_at parameter equal to the current time
linestrings.pre('save', function(next){
    now = new Date();
    this.updated_at = now;
    if(!this.created_at) {
        this.created_at = now
    }
    next();
});

linestrings.index({geo : '2dsphere'});
module.exports = mongoose.model('linestrings', linestrings);

This is how I call the query from the front-end QueryController.js

/** Looks for LineStrings intersecting a given linestring **/
vm.polyIntersect = function () {

   //Taking name from a form
   vm.queryBody = {
                    name : vm.formData.poly1
   };

   // Post the queryBody 
   $http.post('/find-poly-intersection', vm.queryBody)
             .success(function(queryResults) {
                console.log(queryResults);
             })
            .error(function(queryResults) {
                console.log('Error: no results found '+queryResults));
            });
};

This is my Route.js:

/** Requiring Factories **/
var LinestringFactory = require('./factories/linestring.factory.js');

module.exports = function(app) {
  // Retrieves JSON records for all linestrings intersecting a given one
    app.post('/find-poly-intersection', function(req, res) {
        LinestringFactory.findIntersections(req).then( function (linestrings) {
            return res.json(linestrings);
        }, function (error) {
            return res.json(error);
        })
    });
}

This is my LineString.factory.js:

var Linestrings  = require('../models/linestring-model.js');

exports.findIntersections = findIntersections;

/** Finds Linestrings Intersections **/
function findIntersections(req) {
    return new Promise( function (resolve, reject) {
        var lineName       = req.body.name;
        var linestringById = Linestrings.find({name : lineName});
        var linestrings    = Linestrings.find({});

        //Check if that certain linestring exists with Lodash
        if (_.isEmpty(linestringById) || _.isUndefined(linestringById) 
            || _.isNull(linestringById)){
            return reject('No Linestrings found for that Name');
        } else {

        query = linestrings.where({ geo : { $geoIntersects : { $geometry : { type : 'LineString', coordinates : linestringById }}}});

        query.exec(function (err, intersections) {
            if (err){
                return reject(err);
            }
            return resolve(intersections);
        });

    }, function (error) {
        return reject(error);
    })
}

console.log in QueryController gives me always Object {} for any
linestring name.
I'm making sure of inserting [lng, lat] coordinates

Have you any idea on why I can't find any LineString intersecting by Id while I can find them using straight coordinates?

Thanks in advance.

Most helpful comment

Thanks for your response.

Mongoose version - "mongoose": "~4.1.0"

And Debug after that particular query is:

That's what happens when I pass straight coordinates to the query

Query {
  _mongooseOptions: {},
  mongooseCollection: 
   NativeCollection {
     collection: { s: [Object] },
     opts: { bufferCommands: true, capped: false },
     name: 'linestrings',
     collectionName: 'linestrings',
     conn: 
      NativeConnection {
        base: [Object],
        collections: [Object],
        models: [Object],
        config: [Object],
        replica: false,
        hosts: null,
        host: 'localhost',
        port: 27017,
        user: undefined,
        pass: undefined,
        name: 'MeanMapApp',
        options: [Object],
        otherDbs: [],
        _readyState: 1,
        _closeCalled: false,
        _hasOpened: true,
        _listening: true,
        db: [Object] },
     queue: [],
     buffer: false },
  model: 
   { [Function: model]
     hooks: Kareem { _pres: {}, _posts: {} },
     base: 
      Mongoose {
        connections: [Object],
        plugins: [],
        models: [Object],
        modelSchemas: [Object],
        options: [Object] },
     modelName: 'linestrings',
     model: [Function: model],
     db: 
      NativeConnection {
        base: [Object],
        collections: [Object],
        models: [Object],
        config: [Object],
        replica: false,
        hosts: null,
        host: 'localhost',
        port: 27017,
        user: undefined,
        pass: undefined,
        name: 'MeanMapApp',
        options: [Object],
        otherDbs: [],
        _readyState: 1,
        _closeCalled: false,
        _hasOpened: true,
        _listening: true,
        db: [Object] },
     discriminators: undefined,
     schema: 
      Schema {
        paths: [Object],
        subpaths: {},
        virtuals: [Object],
        nested: [Object],
        inherits: {},
        callQueue: [Object],
        _indexes: [Object],
        methods: {},
        statics: {},
        tree: [Object],
        _requiredpaths: undefined,
        discriminatorMapping: undefined,
        _indexedpaths: undefined,
        s: [Object],
        options: [Object] },
     collection: 
      NativeCollection {
        collection: [Object],
        opts: [Object],
        name: 'linestrings',
        collectionName: 'linestrings',
        conn: [Object],
        queue: [],
        buffer: false } },
  schema: 
   Schema {
     paths: 
      { name: [Object],
        'geo.type': [Object],
        'geo.coordinates': [Object],
        created_at: [Object],
        updated_at: [Object],
        _id: [Object],
        __v: [Object] },
     subpaths: {},
     virtuals: { id: [Object] },
     nested: { geo: true },
     inherits: {},
     callQueue: [ [Object], [Object], [Object] ],
     _indexes: [ [Object] ],
     methods: {},
     statics: {},
     tree: 
      { name: [Object],
        geo: [Object],
        created_at: [Object],
        updated_at: [Object],
        _id: [Object],
        id: [Object],
        __v: [Function: Number] },
     _requiredpaths: undefined,
     discriminatorMapping: undefined,
     _indexedpaths: undefined,
     s: { hooks: [Object], queryHooks: [Object] },
     options: 
      { id: true,
        noVirtualId: false,
        _id: true,
        noId: false,
        validateBeforeSave: true,
        read: null,
        shardKey: null,
        autoIndex: null,
        minimize: true,
        discriminatorKey: '__t',
        versionKey: '__v',
        capped: false,
        bufferCommands: true,
        strict: true,
        pluralization: true } },
  op: 'find',
  options: {},
  _conditions: { geo: { '$geoIntersects': [Object] } },
  _fields: undefined,
  _update: undefined,
  _path: undefined,
  _distinct: undefined,
  _collection: 
   NodeCollection {
     collection: 
      NativeCollection {
        collection: [Object],
        opts: [Object],
        name: 'linestrings',
        collectionName: 'linestrings',
        conn: [Object],
        queue: [],
        buffer: false },
     collectionName: 'linestrings' },
  _traceFunction: undefined,
  _castError: null,
  _count: [Function],
  _execUpdate: [Function],
  _find: [Function],
  _findOne: [Function],
  _findOneAndRemove: [Function],
  _findOneAndUpdate: [Function] }
Mongoose: linestrings.find({ geo: { '$geoIntersects': { '$geometry': { type: 'LineString', coordinates: [ [ 27.528, 25.006 ], [ 14.063, 15.591 ] ] } } } }) { fields: undefined }  
POST /find-poly-intersection 200 77.255 ms - 2
[ { geo: { type: 'LineString', coordinates: [ [Object], [Object] ] },
    created_at: Wed Aug 10 2016 14:41:43 GMT+0200 (CEST),
    updated_at: Wed Aug 10 2016 14:41:43 GMT+0200 (CEST),
    __v: 0,
    name: 'poly2',
    _id: 57b428f3170ec81013cf3d26 },
  { geo: { type: 'LineString', coordinates: [ [Object], [Object] ] },
    created_at: Wed Aug 10 2016 14:41:43 GMT+0200 (CEST),
    updated_at: Wed Aug 10 2016 14:41:43 GMT+0200 (CEST),
    __v: 0,
    name: 'poly1',
    _id: 57ab2107505ab11b1bd8422e } ]

When I pass linestringByID I do not get any output in the console.

All 6 comments

Enable mongoose debug mode with require('mongoose').set('debug', true); to see what query mongoose is actually sending. Also, which version of mongoose are you using?

Thanks for your response.

Mongoose version - "mongoose": "~4.1.0"

And Debug after that particular query is:

That's what happens when I pass straight coordinates to the query

Query {
  _mongooseOptions: {},
  mongooseCollection: 
   NativeCollection {
     collection: { s: [Object] },
     opts: { bufferCommands: true, capped: false },
     name: 'linestrings',
     collectionName: 'linestrings',
     conn: 
      NativeConnection {
        base: [Object],
        collections: [Object],
        models: [Object],
        config: [Object],
        replica: false,
        hosts: null,
        host: 'localhost',
        port: 27017,
        user: undefined,
        pass: undefined,
        name: 'MeanMapApp',
        options: [Object],
        otherDbs: [],
        _readyState: 1,
        _closeCalled: false,
        _hasOpened: true,
        _listening: true,
        db: [Object] },
     queue: [],
     buffer: false },
  model: 
   { [Function: model]
     hooks: Kareem { _pres: {}, _posts: {} },
     base: 
      Mongoose {
        connections: [Object],
        plugins: [],
        models: [Object],
        modelSchemas: [Object],
        options: [Object] },
     modelName: 'linestrings',
     model: [Function: model],
     db: 
      NativeConnection {
        base: [Object],
        collections: [Object],
        models: [Object],
        config: [Object],
        replica: false,
        hosts: null,
        host: 'localhost',
        port: 27017,
        user: undefined,
        pass: undefined,
        name: 'MeanMapApp',
        options: [Object],
        otherDbs: [],
        _readyState: 1,
        _closeCalled: false,
        _hasOpened: true,
        _listening: true,
        db: [Object] },
     discriminators: undefined,
     schema: 
      Schema {
        paths: [Object],
        subpaths: {},
        virtuals: [Object],
        nested: [Object],
        inherits: {},
        callQueue: [Object],
        _indexes: [Object],
        methods: {},
        statics: {},
        tree: [Object],
        _requiredpaths: undefined,
        discriminatorMapping: undefined,
        _indexedpaths: undefined,
        s: [Object],
        options: [Object] },
     collection: 
      NativeCollection {
        collection: [Object],
        opts: [Object],
        name: 'linestrings',
        collectionName: 'linestrings',
        conn: [Object],
        queue: [],
        buffer: false } },
  schema: 
   Schema {
     paths: 
      { name: [Object],
        'geo.type': [Object],
        'geo.coordinates': [Object],
        created_at: [Object],
        updated_at: [Object],
        _id: [Object],
        __v: [Object] },
     subpaths: {},
     virtuals: { id: [Object] },
     nested: { geo: true },
     inherits: {},
     callQueue: [ [Object], [Object], [Object] ],
     _indexes: [ [Object] ],
     methods: {},
     statics: {},
     tree: 
      { name: [Object],
        geo: [Object],
        created_at: [Object],
        updated_at: [Object],
        _id: [Object],
        id: [Object],
        __v: [Function: Number] },
     _requiredpaths: undefined,
     discriminatorMapping: undefined,
     _indexedpaths: undefined,
     s: { hooks: [Object], queryHooks: [Object] },
     options: 
      { id: true,
        noVirtualId: false,
        _id: true,
        noId: false,
        validateBeforeSave: true,
        read: null,
        shardKey: null,
        autoIndex: null,
        minimize: true,
        discriminatorKey: '__t',
        versionKey: '__v',
        capped: false,
        bufferCommands: true,
        strict: true,
        pluralization: true } },
  op: 'find',
  options: {},
  _conditions: { geo: { '$geoIntersects': [Object] } },
  _fields: undefined,
  _update: undefined,
  _path: undefined,
  _distinct: undefined,
  _collection: 
   NodeCollection {
     collection: 
      NativeCollection {
        collection: [Object],
        opts: [Object],
        name: 'linestrings',
        collectionName: 'linestrings',
        conn: [Object],
        queue: [],
        buffer: false },
     collectionName: 'linestrings' },
  _traceFunction: undefined,
  _castError: null,
  _count: [Function],
  _execUpdate: [Function],
  _find: [Function],
  _findOne: [Function],
  _findOneAndRemove: [Function],
  _findOneAndUpdate: [Function] }
Mongoose: linestrings.find({ geo: { '$geoIntersects': { '$geometry': { type: 'LineString', coordinates: [ [ 27.528, 25.006 ], [ 14.063, 15.591 ] ] } } } }) { fields: undefined }  
POST /find-poly-intersection 200 77.255 ms - 2
[ { geo: { type: 'LineString', coordinates: [ [Object], [Object] ] },
    created_at: Wed Aug 10 2016 14:41:43 GMT+0200 (CEST),
    updated_at: Wed Aug 10 2016 14:41:43 GMT+0200 (CEST),
    __v: 0,
    name: 'poly2',
    _id: 57b428f3170ec81013cf3d26 },
  { geo: { type: 'LineString', coordinates: [ [Object], [Object] ] },
    created_at: Wed Aug 10 2016 14:41:43 GMT+0200 (CEST),
    updated_at: Wed Aug 10 2016 14:41:43 GMT+0200 (CEST),
    __v: 0,
    name: 'poly1',
    _id: 57ab2107505ab11b1bd8422e } ]

When I pass linestringByID I do not get any output in the console.

You'd probably want to pass in the linestring coordinates as coordinates rather than the whole object:

query = linestrings.where({ geo : { $geoIntersects : 
                   { $geometry : 
                     { type : 'LineString', coordinates : linestringById.geo.coordinates }}}});

Also, you'll need to upgrade, below script works fine with npm install [email protected]

'use strict';

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

mongoose.set('debug', true);

mongoose.connect('mongodb://localhost/gh4408');

var lineStringSchema = new Schema({
        name: String,
        geo: {
          type: { type: String, default: 'LineString' },
          coordinates: Array
        }
      });

      var LineString = mongoose.model('gh4408', lineStringSchema);

      var ls = {
        name: 'test',
        geo: {
          coordinates: [ [14.59, 24.847], [28.477, 15.961] ]
        }
      };
      var ls2 = {
        name: 'test2',
        geo: {
          coordinates: [ [27.528, 25.006], [14.063, 15.591] ]
        }
      };
      LineString.create(ls, ls2, function(error, ls1) {
        assert.ifError(error);
        var query = {
          geo: {
            $geoIntersects: {
              $geometry: {
                type: 'LineString',
                coordinates: ls1.geo.coordinates
              }
            }
          }
        };
        LineString.find(query, function(error, results) {
          assert.ifError(error);
          assert.equal(results.length, 2);
console.log('done'); process.exit(0);
        });
      });

Hey guys i need help:
this query returns empty in nodejs
router.get('/getstateareas/:areas', (req, res) =>{ let areas = req.params.areas CityItem.find({area: areas}) .exec((err, data) => { if(err){ res.status(500).send(err) }else{ res.json(data) console.log(data) } }) })

then Mongoose schema:
`var CitySchema = new Schema({

state: String,
alias: String,
lga: String,
area : String,
area_alias: String,
zipcode: [{type: String}],
street: [{type: String}]

});`
mongoose debug returns this:Mongoose: city_areas.find({ area: 'areas' }, { fields: {} })

please what am I doing wrong?
any help please!

I have the same problem
when I had gone through my code I found that I had not imported the connection file in my index.js file
so mongoose return the object of my query base on my model schema

@Vardhman811 can you please open a new issue and follow the issue template?

Was this page helpful?
0 / 5 - 0 ratings