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

eaf3rand  于 2022-12-29  发布在  Go
关注(0)|答案(1)|浏览(140)

各位。希望你们过得好。我现在有这个问题。
这是我的“旅行”图式。

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

你能帮我解决这个问题吗?先谢了。

w46czmvw

w46czmvw1#

如果我没理解错的话,可以将$min$max$reduce一起使用,因为$indexOfArray返回的是第一次出现的索引,所以不应该在这里使用。因为你可能有相同的坐标多次。使用$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 example上的工作原理

相关问题