1

我做了一个过滤器来对我的 Mongodb 数据库中的数据进行地理空间查询,这个过滤器工作正常,直到我使用另一个地理空间过滤器对该过滤器执行“与”操作,但指向我正在查询的集合上的不同属性。当我添加这个过滤器时,我得到一个异常说明:

消息: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;

通常,当将 & 应用于两个过滤器时,它可以工作,但在这种情况下,有人对此有解决方案吗?

4

1 回答 1

1

您一次只能对一个集合进行一次地理查询。如果您必须在单个文档中存储两个坐标字段,则必须发出两个单独的地理查询,然后在客户端与结果相交。您还需要创建 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"
        }
    }
]
于 2019-06-15T14:54:36.487 回答