0

I am trying to use LineString in $geoNear in a aggregation query, but unable to use it. I want any other alternative to use a LineString to compare list of co-ordinates.

this is my function:

function SentNotifications(coordinates,userid,startdate,enddate)
{
    var listofusers=[];
    console.log(coordinates);
    TripCoordinatesData.aggregate([
        {
            $geoNear: {
              near: { type: "Point", coordinates: coordinates},
              distanceField: "calculated",
              maxDistance: 2
           }
       },       
       { 
           $unwind: "$calculated" 
       },
        {
          $lookup:
            {
              from: "tripdatas",
              localField: "tripdata",
              foreignField: "_id",
              as: "trip"
            }
       },
       { $unwind: "$trip" },

       {
          $lookup:
            {
              from: "userdatas",
              localField: "trip.userdata",
              foreignField: "_id",
              as: "user"
            }
       },
         { $unwind: "$user" },

       {
            $match:
            {
                "trip.userdata":{$ne:mongoose.Types.ObjectId(userid)},
                "trip.createdon":{"$lte" : new Date(startdate)},
                "trip.createdon":{"$gte" : new Date(enddate)},

                //Logged in userid
                "trip.NotificationsSentTo": {$nin:[mongoose.Types.ObjectId(userid)]} 
            }
        },
//        {$group:{_id:{user:{firebaseToken:"$user.firebaseToken"}, trip:'$trip',calculated:'$calculated'}}}
        {$group:{ _id: null,
      users: {
        $addToSet: "$user.firebaseToken"
      }}}

     ],function(err,result){       
         console.log(result);
         console.log(err);

     });
}

This is my request:

{
"id":"0",
"data":[ 
            [
            73.67368340492247,
            18.728638338108293
          ],
          [
            73.67421984672546,
            18.729959229560155
          ]
        ]
}

And here's how i pass data in the function:

SentNotifications(req.body.data,tokenhelper.getUserFromToken(req.headers.token),Date.UTC("2019-05-04T00:00:00Z"),Date.UTC("2019-05-04T23:59:59Z"));

Here are my mongo documents:

/* 1 */
{
    "_id" : ObjectId("5ccda8cd297d56360402ff82"),
    "location" : {
        "coordinates" : [ 
            [ 
                73.6736834049225, 
                18.7286383381083
            ], 
            [ 
                73.6742198467255, 
                18.7299592295602
            ]
        ],
        "type" : "LineString"
    },
    "tripdata" : ObjectId("5ccda8cd297d56360402ff81"),
    "createdon" : ISODate("2019-05-04T14:59:25.720Z"),
    "__v" : 0
}

/* 2 */
{
    "_id" : ObjectId("5ccda96344bdeb24bcdf66f6"),
    "location" : {
        "coordinates" : [ 
            [ 
                73.6736834049225, 
                18.7286383381083
            ], 
            [ 
                73.6742198467255, 
                18.7299592295602
            ]
        ],
        "type" : "LineString"
    },
    "tripdata" : ObjectId("5ccda96344bdeb24bcdf66f5"),
    "createdon" : ISODate("2019-05-04T15:01:55.942Z"),
    "__v" : 0
}

/* 3 */
{
    "_id" : ObjectId("5ccda98044bdeb24bcdf66f7"),
    "location" : {
        "coordinates" : [ 
            [ 
                73.6736834049225, 
                18.7286383381083
            ], 
            [ 
                73.6742198467255, 
                18.7299592295602
            ]
        ],
        "type" : "LineString"
    },
    "tripdata" : ObjectId("5ccda96344bdeb24bcdf66f5"),
    "createdon" : ISODate("2019-05-04T15:02:24.482Z"),
    "__v" : 0
}

So i need a solution where i can use linestring in a aggregate function. Because i am avoiding for loop as its a bad practice.

Edit: i want to compare two line strings, one from the collection and one coming from request, if the distance between the linestrings is less then or equal to 1000 meters, then that collection should return, this is my basic requirement.

Edit 2: I tried this:

     $geoNear:                                                                        
            {
              near: { type: "LineString", coordinates: coordinates},
              distanceField: "calculated",
              maxDistance: 2
           }  

But got this error:

{ MongoError: 'near' field must be point
    at Connection.<anonymous> (D:\Projects\TrackingApp\trackingapp\node_modules\mongoose\node_modules\mongodb-core\lib\connection\pool.js:443:61)
    at emitTwo (events.js:126:13)
    at Connection.emit (events.js:214:7)
    at processMessage (D:\Projects\TrackingApp\trackingapp\node_modules\mongoose\node_modules\mongodb-core\lib\connection\connection.js:364:10)
    at Socket.<anonymous> (D:\Projects\TrackingApp\trackingapp\node_modules\mongoose\node_modules\mongodb-core\lib\connection\connection.js:533:15)
    at emitOne (events.js:116:13)
    at Socket.emit (events.js:211:7)
    at addChunk (_stream_readable.js:263:12)
    at readableAddChunk (_stream_readable.js:250:11)
    at Socket.Readable.push (_stream_readable.js:208:10)
    at TCP.onread (net.js:594:20)
  ok: 0,
  errmsg: '\'near\' field must be point',
  code: 17304,
  codeName: 'Location17304',
  name: 'MongoError',
  [Symbol(mongoErrorContextSymbol)]: {} }   
  • Be happy to suggest alternate approaches, but first probably some explanation of what you expect to happen and the result that is basically required. MongoDB itself has no problem with matching against `LineString`, it's simply just that the "near" and "distance" is calculated from **one** set of the "Point" data coordinates within the `LineString` **only**. Perhaps your problem, but we don't really know what your problem actually is unless you explain it yourself. "need a solution" really does not explain anything. Needs much more clarification. – Neil Lunn May 05 '19 at 07:17
  • @NeilLunn i want to compare two line strings, one from the collection and one coming from request, if the distance between the linestrings is less then or equal to 1000 meters, then that collection should return, this is my basic requirement. – Rushi Mahindrakar May 05 '19 at 08:00
  • `near: { type: "LineString", coordinates: coordinates},` - not really that hard. Also read the comment above since "nearest" is always only the "nearest coordinate pair". The `maxDistance` is also incorrect since the distances returned will be in **meters**, and you certainly don't want to restrict results you just **two meters** only. – Neil Lunn May 05 '19 at 08:26
  • @NeilLunn I tried this: $geoNear: { near: { type: "LineString", coordinates: coordinates}, distanceField: "calculated", maxDistance: 2 } But got this error: { MongoError: 'near' field must be point } – Rushi Mahindrakar May 05 '19 at 15:33

0 Answers0