mongo聚合在具有匹配结果的多个排他条件下“匹配”

时间:2019-05-24 11:47:29

标签: aggregation-framework

想象一下一个数据库,该数据库在每个文档中存储一个位置(纬度,经度)。现在想象一下,我们有许多不重叠的区域,每个区域由一个多边形描述。在单个聚合查询中,我想匹配这些区域中任何一个区域内的位置,但还要获取匹配的区域号。

我可以轻松地检查一个多边形。

db.AIS.aggregate(
    [
        { $match: {
             "pos": {
               $geoWithin: {
                  $geometry: {
                     type : "Polygon" ,
                     coordinates: [ [
                    [
                        -3.581170042968779,
                        53.306942923437504
                    ],
                    [
                        -3.56640117304687,
                        53.301085313281256
                    ],
                    .....
                }
            }
        }
    ]
);

此处的多边形可以替换为多多边形,或者您可以在比赛中使用 $ or 。但是,如果您想知道发生了哪个匹配项并添加一个新字段来表明这一点,那么它似乎无法在 $ match 阶段完成,因为这只会将未修改的匹配文档返回到下一个管道阶段。

有人可以建议一个合适的管道来解决这种通用的多种排他条件匹配模式,并根据匹配添加输出字段吗?


更多说明

我知道 $ geoIntersects 既可以绕圆点工作,例如点与多边形相交,也可以与多边形相交。看一个例子,有人试图确定特定点包含在哪个多边形中,这让我有了一个想法,将所有多边形存储在另一个集合中,然后通过每个点执行 $ lookup 匹配为 $ geoIntersects 。但是,从句法上看,这些地理空间查询不支持除几何部分的常量数据以外的任何其他内容,并且无法使用从集合中查找的字段。我在这里错了吗?

如果确实当前没有执行此查询的方法,那么我认为我的解决方案将是最终不得不检索所有点数据并执行自己的多边形相交测试的解决方案。由于每个点收集可能包含大约12Gb /年,因此这些查询实际上将最终移动大量数据。我宁愿留在数据库中的山脉。

有人成功使用了 $ geoWithin $ geoIntersects ,其中位置和多边形(或其他几何形状)都是集合中的字段。例如,可能处于 $ lookup 阶段。任何人都可以说是否有可能或提供替代解决方案?

更简短的实验...

当然可以使用 $ facet 聚合,例如,类似于以下方式:

db.AIS.aggregate([
    {
        $facet: {
            "zone_0": [
                { $match: { "pos": {$geoWithin: { $geometry: poly[0] } } } }, 
                { $group: {
                    _id: null,
                    n: { $sum: 1 } 
                }}                    
            ],
            "zone_1": [
                { $match: { "pos": {$geoWithin: { $geometry: poly[1] } } } }, 
                { $group: {
                    _id: null,
                    n: { $sum: 1 } 
                }}                    
            ]
        }
    }
]);

其中poly是用JS代码初始化的GeoJSON多边形数组

但是,这无疑可以对照所有多边形检查每个点。这也意味着当区域多边形彼此接触时,一个点可能会匹配两个区域。在只有2Gb点数据(有线老虎)的真实数据库上进行测试,仅用两个多边形就花费了很多分钟。看起来它的伸缩性不是很好,并且由于对所有数据进行批量检索比这种查询要快,因此在Mongo之外执行处理也许是有意义的。

也许将来可能会使用有条件的 $ addFields ,但语法类似于 $ match 的东西可能会有用,但据我所知不存在。一些简单的布尔地理空间比较运算符(例如 $ geoWithin / Intersects -可在 $ project 中使用的函数样式)也可能会有所帮助。

当数据集同时包含位置和时间时,您不仅可能不得不重新对结果进行排序,而且还可能最终无法利用2dsphere索引(如果您先按时间进行过滤)。

其他人可能正在存储类似于我的地理空间数据,并希望执行类似的处理,因此,如果您在外面,请分享您的想法。

0 个答案:

没有答案