在MongoDB投影聚合中,如何访问特定的数组项?

7

我正在尝试在MongoDB聚合函数中创建一个投影,如下所示:

[
    {$match : {"geo" : {$ne: null}}},
    {$project : {"id" : "$id_str", lat: "$geo.coordinates.0", lon: "$geo.coordinates.1"}}
]

然而,当我这样做时,它并没有传递数组项,只是将空数组投影到属性lat和lon上。
需要什么?我查看了文档,但无法弄清楚,甚至尝试了$unwind和$group的排列组合,但没有成功。
2个回答

5
目前还没有可用的功能实现此操作。但是,对于 MongoDB 版本为 3.2.X 及以上版本,可以使用一个新的聚合运算符来返回给定索引处的数组元素。这个新表达式叫做 $arrayElemAt。它接受两个参数:一个数组和一个索引,并返回数组中给定索引处的元素。负索引将被解释为从数组末尾开始的索引。如果索引超出了数组的界限,则返回缺失值,也就是说,输出中不会包含该字段。
var pipeline = [    
    { $match : {"geo" : {$ne: null}}},
    {
        $project: {
            _id: "$id_str", 
            lat: { $arrayElemAt: ['$geo.coordinates', 0] },
            lon: { $arrayElemAt: ['$geo.coordinates', 1] }
        }
    }
];

目前的解决方法是(假设坐标数组始终在任何给定时间都有两个元素),您可以尝试以下聚合管道,它将利用$first$last群组累加器运算符,在$sort之后获取元素:
var pipeline = [
    {$match : {"geo" : {$ne: null}}},
    { "$unwind": "$geo.coordinates" },
    { "$sort": {"geo.coordinates": 1} } ,
    {
        "$group": {
            "_id": "$_id",
            "lat": { "$first": "$geo.coordinates" },
            "lon": { "$last": "$geo.coordinates" }
        }
    }
];

1

在管道的项目阶段中,您可以简单地使用以下内容:

{ $project:{ _id:'$_id', lat: {$arrayElemAt : ['$geo.coordinates',0]}, lon: {$arrayElemAt : ['$geo.coordinates',1]}, } }

如果您想更详细地了解arrayElemAt聚合运算符,请单击下面给出的链接:

https://docs.mongodb.com/manual/reference/operator/aggregation/arrayElemAt/

更多信息:

“所有文档必须按照相同的顺序存储位置数据。如果您使用经度和纬度作为坐标系,请始终首先存储经度。MongoDB的2d球形索引运算符仅识别[经度,纬度]排序。”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接