mongodb - 除了查找另一个集合之外,如何使用 geoNear 按距离排序

2024-01-03

我有两个单独工作的功能,但想将它们组合起来。

  • 功能 1 - 按地理邻近距离对用户进行排序。
  • 功能 2 - 用户不应该已经被喜欢 当前用户(查找partnership收藏)

如何更新此查询以从用户的集合开始,以便我可以执行 geoNear?

下面 mongoplayground 中的输出是正确的,只是生成的用户未按以下顺序排序calculatedDist这是由 geoNear 计算的字段。

$geoNear: {
   near: { type: "Point", coordinates: [x,y },
   distanceField: "calculatedDist",
   spherical: true
}

geoNear 需要仅在用户集合中可用的位置,因此我认为需要修改以下查询以在用户集合中启动。https://mongoplayground.net/p/7H_NxciKezB https://mongoplayground.net/p/7H_NxciKezB

db={
  users: [
    {
      _id: "abc",
      name: "abc",
      group: 1,
      location: {
        type: "Point",
        coordinates: [
          54.23,
          67.12
        ]
      },
      calculatedDist: 13
    },
    {
      _id: "xyz",
      name: "xyyy",
      group: 1,
      location: {
        type: "Point",
        coordinates: [
          54.23,
          67.12
        ]
      },
      calculatedDist: 11
    },
    {
      _id: "123",
      name: "yyy",
      group: 1,
      location: {
        type: "Point",
        coordinates: [
          54.23,
          67.12
        ]
      },
      calculatedDist: 2
    },
    {
      _id: "rrr",
      name: "tttt",
      group: 1,
      location: {
        type: "Point",
        coordinates: [
          54.23,
          67.12
        ]
      },
      calculatedDist: 11
    },
    {
      _id: "eee",
      name: "uuu",
      group: 1,
      location: {
        type: "Point",
        coordinates: [
          54.23,
          67.12
        ]
      },
      calculatedDist: 7
    },
    
  ],
  partnership: [
    {
      _id: "abc_123",
      fromUser: "abc",
      toUser: "123"
    },
    {
      _id: "eee_rrr",
      fromUser: "eee",
      toUser: "rrr"
    },
    {
      _id: "rrr_abc",
      fromUser: "rrr",
      toUser: "abc"
    },
    {
      _id: "abc_rrr",
      fromUser: "abc",
      toUser: "rrr"
    },
    {
      _id: "xyz_rrr",
      fromUser: "xyz",
      toUser: "rrr"
    },
    {
      _id: "rrr_eee",
      fromUser: "rrr",
      toUser: "eee"
    },
    
  ]
}

据我所知,geoNear 必须是首先要做的事情,所以我的查询应该从users收藏。这破坏了我的合作伙伴关系检查,因为要使其发挥作用,我从partnership收藏。

在上面的操场上,用户eee由于 geoNear,计算距离较小,但它在用户之后显示abc.


试试这个:

db.partnership.aggregate([
  // $geoNear
  {
    $match: {
      $or: [
        {
          fromUser: "rrr"
        },
        {
          toUser: "rrr"
        }
      ]
    }
  },
  {
    $group: {
      _id: 0,
      from: {
        $addToSet: "$fromUser"
      },
      to: {
        $addToSet: "$toUser"
      }
    }
  },
  {
    $project: {
      _id: 0,
      users: {
        $filter: {
          input: {
            $setIntersection: [
              "$from",
              "$to"
            ]
          },
          cond: {
            $ne: [
              "$$this",
              "rrr"
            ]
          }
        }
      }
    }
  },
  {
    $lookup: {
      from: "users",
      let: {
        userId: "$users"
      },
      pipeline: [
        {
          "$geoNear": {
            "near": {
              "type": "Point",
              "coordinates": [
                31.4998,
                -61.4065
              ]
            },
            "distanceField": "calculatedDist",
            "spherical": true
          }
        },
        {
          "$match": {
            "$expr": {
              "$in": [
                "$_id",
                "$$userId"
              ]
            }
          }
        }
      ],
      as: "users"
    }
  },
  {
    $project: {
      users: 1,
      count: {
        $size: "$users"
      }
    }
  }
])

在这里,我们使用管道形式的查找。

  1. 查找是在用户的集合上进行的,我们在其中指定一个管道$geoNear阶段作为第一阶段。
  2. 最后过滤掉,只保留属于合作伙伴的用户。

这是游乐场链接 https://mongoplayground.net/p/sqdorq_LZDq。让我知道它是否有效,在操场上我无法测试它,因为$geoNear需要一个2d index.

使用时calculatedDist,它看起来像这样:

db.partnership.aggregate([
  // $geoNear
  {
    $match: {
      $or: [
        {
          fromUser: "rrr"
        },
        {
          toUser: "rrr"
        }
      ]
    }
  },
  {
    $group: {
      _id: 0,
      from: {
        $addToSet: "$fromUser"
      },
      to: {
        $addToSet: "$toUser"
      }
    }
  },
  {
    $project: {
      _id: 0,
      users: {
        $filter: {
          input: {
            $setIntersection: [
              "$from",
              "$to"
            ]
          },
          cond: {
            $ne: [
              "$$this",
              "rrr"
            ]
          }
        }
      }
    }
  },
  {
    $lookup: {
      from: "users",
      let: {
        userId: "$users"
      },
      pipeline: [
        {
          $sort: {
            calculatedDist: 1
          }
        },
        {
          "$match": {
            "$expr": {
              "$in": [
                "$_id",
                "$$userId"
              ]
            }
          }
        }
      ],
      as: "users"
    }
  },
  {
    $project: {
      users: 1,
      count: {
        $size: "$users"
      }
    }
  }
])

操场 https://mongoplayground.net/p/jxsw8WAFLCX.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

mongodb - 除了查找另一个集合之外,如何使用 geoNear 按距离排序 的相关文章

随机推荐