【问题标题】:Need a workaround for lookup of a string to objectID foreignField需要一种解决方法来查找 objectID foreignField 的字符串
【发布时间】:2018-01-16 07:35:15
【问题描述】:

我是 mongodb 的新手,目前我正面临这个问题,

db.medical_records.aggregate([
    {
        "$group": {
            "_id": {
                "disease_id": "$disease_id" //a string
            }, "count": { "$sum": 1 }
        }
    },
    {
        "$addFields": {
            "disease_id": { "$toObjectId": "$disease_id" } 
            // i tried to change it into objectID so i could $lookup it
        }
    },
    {
        "$lookup": {
            "from": "diseases", 
            "localField": "disease_id", 
            "foreignField": "_id", 
            "as": "disease"
        }
    }
])

这是我收集病历的一个例子

{
    "_id" : ObjectId("5989c8f13f3958120800682e"),
    "disease_id" : "5989c8f13f3958120800682f",
    "patient_id" : "5989c8f13f3958120800681f"
}

疾病收集

{
    "_id" : ObjectId("5989c8f13f3958120800682f"),
    "name" : "Culpa autem officia.",
    "code" : "Est aperiam."
}

我期望的结果是,

{
    "_id" : {disease_id: 5989c8f13f3958120800682f},
    "count" : 20,
    "disease" : {
        "_id" : ObjectId("5989c8f13f3958120800682f"),
        "name" : "Culpa autem officia.",
        "code" : "Est aperiam."
    }
}

如上所述,我需要将我的病历收集加入疾病收集。

当我尝试将其查找到疾病集合时,它失败了,因为 foreignField 与 localField 的类型不同。我一直在尝试寻找解决此问题的方法。而上面的查询又返回了一个错误,

Unrecognized expression '$toObjectId'

这个问题可能已经被问过好几次了,但是我真的需要解决这个问题,请帮助

【问题讨论】:

  • 您能否更新您的问题以包括:(1) 来自 Medical_records 集合的示例文档; (2) 疾病收集的样本文件; (3) 显示您想要的结果的示例文档。
  • 编辑:再谷歌搜索后,我意识到 $toObjectId 是不存在的聚合器,因此该错误是预期的结果。

标签: mongodb


【解决方案1】:

4.0 中的新功能:https://docs.mongodb.com/manual/reference/operator/aggregation/toObjectId/

// Define stage to add convertedId field with converted _id value

idConversionStage = {
   $addFields: {
      convertedId: { $toObjectId: "$_id" }
   }
};

// Define stage to sort documents by the converted qty values

sortStage = {
   $sort: { "convertedId": -1 }
};


db.orders.aggregate( [
   idConversionStage,
   sortStage
])

【讨论】:

    【解决方案2】:

    哇...在浏览完所有文档和 stackoverflow 答案后,我想推荐一个简单的修复方法。

    将您的 users_id 或任何文档对象 ID 保存在另一个集合中时,请确保 dataType 保持为 ObjectId 或在保存文档之前将其转换为 ObjectId。

    然后单独使用 Mongodb 上的文档,而不尝试强制转换或绑定。

    db.orders.aggregate([
       {
         $lookup:
           {
             from: "users",
             localField: "user_id",
             foreignField: "_id",
             as: "inventory_docs"
           }
      }
    ]) 
    
    This case user_id is coming from your current model then _id is coming from your users collections which both are already ObjectId by Origin. 
    

    【讨论】:

    • 问题本身的重点不是做你刚刚回答的事情
    【解决方案3】:

    例如,将 ref 保存到新集合时。订单集合中的 user_id。确保 dataType 是 ObjectID。那么您可以使用 ObjectID 而无需转换。例如车辆和司机集合。默认情况下,聚合会将 dataType 匹配到 dataType 这也可以保持查询的速度。

    
     await Vehicle.aggregate([{
        $lookup: {
          from: 'users', 
          localField: "driver_id", 
          foreignField: "_id", 
          as: "users"
        }
      }]).then(vehicles => {
        data.status   = 200;
        data.message  = "Vehicles retreived!";
        data.data     = vehicles;
      }).catch(err => {
        // console log value
        console.log(err);
        data.status   = 500;
        data.message  = "Error retreiving vehicle";
        data.data     = JSON.stringify(err);
      });
    
    
    

    【讨论】:

      【解决方案4】:

      答案仅适用于版本

      这不能用你当前的数据结构来完成。

      另见此处:Mongoose $lookup where localField is a string of an ObjectId in foreignField

      在这里:Is it possible to compare string with ObjectId via $lookup

      但是,为什么不将您的病历集合中的数据更改为:

      {
          "_id" : ObjectId("5989c8f13f3958120800682e"),
          "disease_id" : ObjectId("5989c8f13f3958120800682f"), // note the ObjectId
          "patient_id" : ObjectId("5989c8f13f3958120800681f") // note the ObjectId
      }
      

      鉴于这种格式,您可以使用以下查询获得您想要的:

      db.medical_records.aggregate([
          {
              "$group": {
                  "_id": {
                      "disease_id": "$disease_id" //a string
                  }, "count": { "$sum": 1 }
              }
          },
          {
              "$lookup": {
                  "from": "diseases", 
                  "localField": "_id.disease_id", 
                  "foreignField": "_id", 
                  "as": "disease"
              }
          }
      ])
      

      编辑根据您在下面的评论:

      MongoDB 中没有 $toObjectId 运算符。试试searching the documentation,你什么也找不到!因此,如果不更改数据,根本无法实现您的目标。我不知道您提到的“雄辩的 laravel-mongodb”框架,但根据它的文档,我认为您的模型可能需要一些调整。你现在如何塑造你们的关系?

      【讨论】:

      • 实际上我正在使用一个框架库(雄辩的 laravel-mongodb)来保存我的数据。但是对于更复杂的查询,我不得不使用聚合并且我做不了太多。我目前要问的是如何正确使用 $toObjectId ?如果不是因为上面的错误可能会成为这种情况的解决方法
      猜你喜欢
      • 1970-01-01
      • 2017-10-15
      • 1970-01-01
      • 1970-01-01
      • 2021-05-24
      • 1970-01-01
      • 1970-01-01
      • 2012-06-23
      • 2021-05-23
      相关资源
      最近更新 更多