Фильтрация нескольких операций Geo Near в запросе приводит к ошибке - PullRequest
1 голос
/ 27 мая 2019

Я сделал фильтр для выполнения геопространственного запроса к данным из моей базы данных Mongodb, и этот фильтр работает нормально, пока я не выполню операцию «И» над этим фильтром с другим геопространственным фильтром, но указываю на другое свойство в коллекции I ». м запрос Когда я добавляю этот фильтр, я получаю исключение:

Сообщение: MongoDB.Driver.MongoCommandException: сбой при поиске команды: слишком много выражений geoNear.

Вот первый фильтр,


                var point = GeoJson.Point(GeoJson.Geographic(longitude: annEntityaAttr.CollectionLocation.Longitude,
                    latitude: annEntityaAttr.CollectionLocation.Latitude));
                filter = Builders<AnnouncementEntity>.Filter.Near(a => a.CollectionLocation, point, annEntityaAttr.MaxDistanceFromLocationInKM * metersFor1KM);

Вот как я добавляю второй фильтр:

var point = GeoJson.Point(GeoJson.Geographic(longitude: annEntityaAttr.DepositLocation.Longitude,
                    latitude: annEntityaAttr.DepositLocation.Latitude));
                var secondFilter = Builders<AnnouncementEntity>.Filter.Near(a => a.DepositLocation, point, annEntityaAttr.MaxDistanceFromLocationInKM * metersFor1KM);

filter = filter & secondFilter;

Обычно, когда применяется & к двум фильтрам, это работает, но в этом случае не радует, есть ли у кого-то решение для этого?.

1 Ответ

1 голос
/ 15 июня 2019

вы можете выполнять только один гео-запрос для одной коллекции за раз.если вам необходимо сохранить два поля координат в одном документе, вам нужно будет выполнить два отдельных гео-запроса и затем пересечь результаты на стороне клиента.Также вам нужно будет создать 2 географических индекса и указать ключ индекса при запросе.Вот пример программы, которая использует мою библиотеку MongoDB.Entities для достижения того, что вам нужно.

using MongoDB.Entities;
using MongoDB.Driver;
using System.Linq;

namespace StackOverflow
{
    public class Program
    {
        public class Announcement : Entity
        {
            public Coordinates2D CollectionLocation { get; set; }
            public Coordinates2D DepositLocation { get; set; }
            public double DistanceMeters { get; set; }
        }

        static void Main(string[] args)
        {
            new DB("test");

            DB.Index<Announcement>()
              .Key(a => a.CollectionLocation, KeyType.Geo2DSphere)
              .Create();

            DB.Index<Announcement>()
              .Key(a => a.DepositLocation, KeyType.Geo2DSphere)
              .Create();

            (new Announcement
            {
                DepositLocation = new Coordinates2D(48.8539241, 2.2913515),
                CollectionLocation = new Coordinates2D(48.796964, 2.137456)
            }).Save();

            var searchPointA = new Coordinates2D(48.796964, 2.137456);

            var queryA = DB.GeoNear<Announcement>(
                                NearCoordinates: searchPointA,
                                DistanceField: a => a.DistanceMeters,
                                IndexKey: "CollectionLocation",
                                MaxDistance: 10);

            var searchPointB = new Coordinates2D(48.8539241, 2.2913515);

            var queryB = DB.GeoNear<Announcement>(
                                NearCoordinates: searchPointB,
                                DistanceField: a => a.DistanceMeters,
                                IndexKey: "DepositLocation",
                                MaxDistance: 10);

            var resultA = queryA.ToList();
            var resultB = queryB.ToList();

            var common = resultA.Where(a => resultB.Any(b => b.ID == a.ID)).ToArray();
        }
    }
}

Будут выполнены следующие два запроса $ geoNear для поиска местоположений:

[
    {
        "$geoNear": {
            "near": {
                "type": "Point",
                "coordinates": [
                    48.8539241,
                    2.2913515
                ]
            },
            "distanceField": "DistanceMeters",
            "spherical": true,
            "maxDistance": NumberInt("10"),
            "key": "DepositLocation"
        }
    }
]

[
    {
        "$geoNear": {
            "near": {
                "type": "Point",
                "coordinates": [
                    48.796964,
                    2.137456
                ]
            },
            "distanceField": "DistanceMeters",
            "spherical": true,
            "maxDistance": NumberInt("10"),
            "key": "CollectionLocation"
        }
    }
]
...