【问题标题】:Filtering several Geo near operations in a query sends an error在查询中过滤多个 Geo near 操作会发送错误
【发布时间】:2019-10-12 13:16:33
【问题描述】:

我做了一个过滤器来对我的 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;

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

【问题讨论】:

    标签: c# mongodb .net-core mongodb-.net-driver mongodb-geospatial


    【解决方案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"
            }
        }
    ]
    

    【讨论】:

    • 匹配查询末尾的 Id 以查看那些有兴趣的人。真棒聪明的举动!!!谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-07
    • 2013-03-20
    • 1970-01-01
    • 2013-07-01
    • 1970-01-01
    • 2020-06-27
    相关资源
    最近更新 更多