2020-03-05 Mongodb異なるタイプのキー間で集約を使用する方法


質問:Mongodb Join on_id field from String to ObjectIdには、2つのセットのデータがあります.
  • 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は2つの集合をつなぎ合わせる.
    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. (必要なのは、弟さん、このように調べることができます!)
    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"
      }}
    ])

    元のディスカッションの表示は何らかの理由でブロックされてアクセスできない可能性があります.分かります.