繁体   English   中英

在对象数组中按顺序查找开始和结束 - MongoDB

[英]Find start and end in order in an array of objects - MongoDB

每个人。 希望你一切顺利。 我目前有这个问题。

这是我的“旅行”模式。

    const TravelSchema = new mongoose.Schema({
        ...
        route: [{
            index: { type: Number},
            lat: { type: Number },
            lng: { type: Number },
        }],
        ...
    });

这是我处理发布请求的地方。 (保存新旅行)

    ...
    const {route, ...rest} = req.body;
    const newTravel = new Travel({
        route: route.map((location, index) => ({index, ...location})),
        ...rest
    });
    const Travel = await newTravel.save();
    ...

按顺序搜索开始和结束位置。 起始位置和结束位置是具有“lat”和“lng”属性的对象。

    ...
    const { start, end } = req.body;
    //start -> {lat: 51.11213, lng: 19.1239219} //for example
    const travels = await Travel.find({
        route: { $all: [ {$elemMatch: {...start}}, {$elemMatch: {...end}} ] },
        $expr: {
            $lt: [
                {$arrayElemAt: ['$route.index', {$indexOfArray: ['$route', {...start}]}]},
                {$arrayElemAt: [{$reverseArray: '$route.index'}, {$indexOfArray: [{$reverseArray: '$route'}, {...end}]}]},
            ]
        }
    });
    console.log(travels); // [] is printed
    ...

没有 $expr,我可以得到一些结果,但不是准确的结果。 我想要的是这样的:

    route: [{index: 0, lat: 54, lng: 13},  //same as end but not considered regarding order
            {index: 1, lat: 32, lng: 51},
            {index: 1, lat: 10, lng: 30},  //start
            {index: 2, lat: 54, lng: 13}]  //end
    start: {lat: 10, lng: 30}, end: {lat: 54, lng: 13}
    the route is filtered

    route: [{index: 0, lat: 54, lng: 13},  //end
            {index: 1, lat: 32, lng: 51},
            {index: 1, lat: 10, lng: 30}]  //start
    start: {lat: 10, lng: 30}, end: {lat: 54, lng: 13}
    the route is not filtered this time

你能帮我解决这个问题吗? 提前致谢。

如果我理解正确,您可以将$min$max$reduce一起使用。 由于$indexOfArray返回第一次出现的索引,因此不应在此处使用它,因为您可能多次使用相同的 corrdinated。 使用$reduce可以为起点和终点创建所有相关索引的数组。 使用$min$max可以检查是否存在小于终点索引的起点索引:

db.collection.find({
  route: {$all: [ {$elemMatch: {...start}}, {$elemMatch: {...end}} ] },
  $expr: {$lt: [
      {$min: {
          $reduce: {
            input: "$route",
            initialValue: [],
            in: {
              $cond: [
                {$and: [{$eq: ["$$this.lat", start.lat]}, {$eq: ["$$this.lng", start.lng]}]},
                {$concatArrays: ["$$value", ["$$this.index"]]},
                "$$value"
              ]
            }
          }
      }},
      {$max: {
          $reduce: {
            input: "$route",
            initialValue: [],
            in: {
              $cond: [
                {$and: [{$eq: ["$$this.lat", end.lat]}, {$eq: ["$$this.lng", end.lng]}]},
                {$concatArrays: ["$$value", ["$$this.index"]]},
                "$$value"
              ]
            }
          }
      }}
    ]
  }
})

playground 示例中查看它是如何工作的

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM