2020-03-05 Mongodb如何在不同类型键之间使用聚合

问题:Mongodb Join on _id field from String to ObjectId
现在有两个集合的数据:

  1. User
{
   "_id" : ObjectId("584aac38686860d502929b8b"),
   "name" : "John"
}

2.Role

{
   "_id" : ObjectId("584aaca6686860d502929b8d"),
   "role" : "Admin",
   "userId" : "584aac38686860d502929b8b"  
}

I want to join these collection based on the userId (in role collection) - _id ( in user collection).
我想基于userId和_id讲两个集合拼接起来。

I tried the below query:
我尝试了以下查询

db.role.aggregate({
  "$lookup": {
    "from": "user",
    "localField": "userId",
    "foreignField": "_id",
    "as": "output"
  }
})

This gives me expected results as long as i store userId as a ObjectId. When my userId is a string there are no results. Ps: I tried
当userId为String类型时,没有结果。

foreignField: '_id'.valueOf()

and

foreignField: '_id'.toString()

But no luck to match/join based on a ObjectId-string fields.
这样也失败。
Any help will be appreciated.(有老铁能帮帮我吗?)

The previous tickets were fixed in MongoDB 4.0. You can now achieve this with the folowing query:
(必须的,老弟,你能这么查询!)

db.user.aggregate([
  {
    "$project": {
      "_id": {
        "$toString": "$_id"
      }
    }
  },
  {
    "$lookup": {
      "from": "role",
      "localField": "_id",
      "foreignField": "userId",
      "as": "role"
    }
  }
])

result:(结果)


[
  {
    "_id": "584aac38686860d502929b8b",
    "role": [
      {
        "_id": ObjectId("584aaca6686860d502929b8d"),
        "role": "Admin",
        "userId": "584aac38686860d502929b8b"
      }
    ]
  }
]

try it online: mongoplayground.net/p/JoLPVIb1OLS
在这有更多的信息。

或者你也可以尝试如下两种查询:
You can use $toObjectId aggregation from mongodb 4.0 which converts String id to ObjectId

db.role.aggregate([
  { "$lookup": {
    "from": "user",
    "let": { "userId": "$_id" },
    "pipeline": [
      { "$addFields": { "userId": { "$toObjectId": "$userId" }}},
      { "$match": { "$expr": { "$eq": [ "$userId", "$$userId" ] } } }
    ],
    "as": "output"
  }}
])

Or you can use $toString aggregation from mongodb 4.0 which converts ObjectId to String

db.role.aggregate([
  { "$addFields": { "userId": { "$toString": "$_id" }}},
  { "$lookup": {
    "from": "user",
    "localField": "userId",
    "foreignField": "userId",
    "as": "output"
  }}
])

查看原始的讨论
可能被某些原因拦截无法访问,你懂的!

你可能感兴趣的:(sql,mongodb,数据库,nosql)