Фильтруйте по $ geoNear (пункт назначения) и сортируйте по $ geoNear (источник) - PullRequest
0 голосов
/ 02 сентября 2018

Я хочу показать места для гонщиков на заданном расстоянии и отсортировать их по точкам отправления.

Вот так выглядят данные

{ 
"_id" : ObjectId("5b5a9cd706f9b02068ebc4a6"), 
"name" : "Bangalore to hyderabad",
"locations" : [
    {
        "coordinates" : [
            77.5945627, 
            12.9715987
        ], 
        "_id" : ObjectId("5b5a9cd706f9b02068ebc4a8"), 
        "formattedAddress" : "Bengaluru, Karnataka, India", 
        "name" : "Bengaluru", 
        "type" : "Point", 
        "googlePlaceId" : "5b0d9fd719c9616d747b8a0d", 
        "placeType" : "origin" //***Sort by this***
    }, 
    {
        "coordinates" : [
            78.486671, 
            17.385044
        ], 
        "_id" : ObjectId("5b5a9cd706f9b02068ebc4a7"), 
        "formattedAddress" : "Hyderabad, Telangana, India", 
        "name" : "Hyderabad", 
        "type" : "Point", 
        "googlePlaceId" : "5b0d9fd719c9616d747b8a0d", 
        "locType" : "destination" // *****Filter by this***
    }
], 

}

Это домашняя работа, которую я сделал до сих пор.

return await Ride.aggregate([
    {
        $geoNear: {
            near: { type: "Point", coordinates: [ 77.5946,12.8716 ] },
            distanceField: "distance",
            maxDistance: 20000000, //200Kms
            query: { private: false },
            spherical: true
        }
    },
    // { "$sort": { "distance": 1 } },
    { "$skip": 0 },
    { "$limit": 30 }
]);

Этот запрос фильтрует данные по всем точкам местоположения независимо от locType.

2dsphere является индексом для location.coordinates

{ 
"v" : NumberInt(2), 
"key" : {
    "locations.coordinates" : "2dsphere"
}, 
"name" : "locations.coordinates_2dsphere", 
"ns" : "projectName.documentName", 
"background" : true, 
"2dsphereIndexVersion" : NumberInt(3)

}

1 Ответ

0 голосов
/ 04 сентября 2018

Я решил эту проблему другим подходом.

Сначала я добавил поле расстояния к своим данным. Сделано начало и место назначения как отдельный объект вместо массива.

{ 
"_id" : ObjectId("5b5a9cd706f9b02068ebc4a6"), 
"name" : "Bangalore to hyderabad",
"origin" : {
        "coordinates" : [
            77.5945627, 
            12.9715987
        ], 
        "_id" : ObjectId("5b5a9cd706f9b02068ebc4a8"), 
        "formattedAddress" : "Bengaluru, Karnataka, India", 
        "name" : "Bengaluru", 
        "type" : "Point", 
        "googlePlaceId" : "5b0d9fd719c9616d747b8a0d", 
    }, 
destination: {
        "coordinates" : [
            78.486671, 
            17.385044
        ], 
        "_id" : ObjectId("5b5a9cd706f9b02068ebc4a7"), 
        "formattedAddress" : "Hyderabad, Telangana, India", 
        "name" : "Hyderabad", 
        "type" : "Point", 
        "googlePlaceId" : "5b0d9fd719c9616d747b8a0d", 
    }

И затем я сделал запрос на запуск geoNear в исходном поле с радиусом 1 км и запросом расстояния менее 200 км.

Ride.aggregate([
    {
        $geoNear: {
            near: { type: "Point", coordinates: [ 77.5946,12.8716 ] },
            distanceField: "distanceFromOrigin",
            maxDistance: 1000, //1Km
            query: { private: false, distance:{$lt:200}},
            spherical: true
        }
    },
    // { "$sort": { "distanceFromOrigin":1,"distance": 1 } },
    { "$skip": 0 },
    { "$limit": 30 }
]);
...