jjzjj

javascript - $lookup 深度嵌套对象

coder 2023-11-07 原文

我是 MongoDB 的新手,目前正在为学校开发一款建议饮食计划的食谱应用程序。因此,我需要将用户饮食计划(集合“Users”)中的“膳食”ObjectId 与集合“Meals”中的 ObjectId 结合起来。

之后,我需要在“Meals”集合中加入一个“ingredient”ObjectID,其中包含“Ingredients”集合中“ingredient”的 ID。问题是,集合“Meals”中的“成分”ObjectID 位于具有另一个整数变量“amount”的对象中。该对象嵌套在一个名为“ingredients”的数组中,其中包含许多对象,例如刚刚描述的对象。

下面是我的结构:

用户

{
 "_id": ObjectId("5b28cab902f28e18b863bd36"),
 "username: "testUser1",
 "password": "$2a$08$KjddpaSQPjp6aF/gseOhVeddYdqWJCJ4DpFwxfNgsk81G.0TOtN5i",
 "dietPlans": Object
    {
     "dietPlanCurrent":Object
         {
          "monday":Object
               {
               "breakfast":Object
                    {
                     "meal": ObjectId("5b2b9a8bbda339352cc39ec4")
                 },
                 … 
           },
           … 
     },
     …
  },
}

膳食

{
   "_id" : ObjectId("5b2b9a8bbda339352cc39ec4"),
   "name": "Gulasch-breakfast",
   "cuisine": "International",
   "ingredients":[
       {
            "ingredient": ObjectId("5b1ec0f939b55efcd4e28a2d"),
            "amount": 20
       },
       {
            "ingredient": ObjectId("5b1ec42474fc1f58d84264d4"),
            "amount": 20
       },
       {
            "ingredient": ObjectId("5b1ec42474fc1f58d84264d5"),
            "amount": 20
       },
       …   
    ],

   "comments": [
        …
    ]
}

成分

{ 
    {
     "_id": ObjectId("5b1ec0f939b55efcd4e28a2d"),
     "name": "Walnut",
     "calories": 654
      … 
    }
    {
     "_id": ObjectId("5b1ec0f939b55efcd4e28a3d"),
     "name": "Apple",
     "calories": 123
     … 
    }
… 
}

我想得到的是:

    {
 "_id": ObjectId("5b28cab902f28e18b863bd36"),
 "username: "testUser1",
 "password": "$2a$08$KjddpaSQPjp6aF/gseOhVeddYdqWJCJ4DpFwxfNgsk81G.0TOtN5i",
 "dietPlans": Object
    {
     "dietPlanCurrent":Object
         {
          "Monday":Object
               {
               "breakfast":Object
                    {
                     "meal": ObjectId("5b2b9a8bbda339352cc39ec4")
                     "matchedIngredients": [
                        {
                         "_id": ObjectId("5b1ec0f939b55efcd4e28a2d"),
                         "name": "Walnut",
                         "calories": 654
                         … 
                        }
                      … 
                      ]

                 },


                 … 
           },


           … 
     },
     …
  },
}

我的方法无效(只返回空的 matchedIngredients 数组)

    {
        $match: {
            '_id': mongoose.Types.ObjectId(req.params.userId)
        }
    },
    {
        $lookup:   {
            from: 'meals',
            localField: 'dietPlans.dietPlanCurrent.monday.breakfast.meal',
            foreignField: '_id',
            as: "dietPlans.dietPlanCurrent.monday.breakfast.mealObject"
        }              
    },
    {
        $unwind: {
            path: "$dietPlans.dietPlanCurrent.monday.breakfast.mealObject",
            preserveNullAndEmptyArrays: true
        }
    },
   {
        $unwind: {
               path: "$dietPlans.dietPlanCurrent.monday.breakfast.mealObject.ingredients",
            preserveNullAndEmptyArrays: true
        }
    },
    {
        $lookup:   {
            from: 'ingredients',
            localField: 'dietPlans.dietPlanCurrent.monday.breakfast.mealObject.ingredients.ingredient',
            foreignField: '_id',
            as: "dietPlans.dietPlanCurrent.monday.breakfast.matchedIngredients"
        }              
    }

非常感谢您的帮助。我已经检查了这种方法,但不知何故它不起作用:

Approach that didn't work for me

非常感谢!

最佳答案

mongodb 版本 3.4 无法执行您尝试执行的操作,但如果您升级到 3.6,则可以尝试以下聚合

db.collection.aggregate([
  { "$match": { "_id": mongoose.Types.ObjectId(req.params.userId) } },
  { "$lookup": {
    "from": Meals.collection.name,
    "let": { "meal_id": "$dietPlans.dietPlanCurrent.monday.breakfast.meal" },
    "pipeline": [
      { "$match": { "$expr": { "$eq": [ "$_id", "$$meal_id" ] } } },
      { "$unwind": "$ingredients" },
      { "$lookup": {
        "from": Ingredients.collection.name,
        "let": { "ingredient_id": "$ingredients.ingredient" },
        "pipeline": [
          { "$match": { "$expr": { "$eq": [ "$_id", "$$ingredient_id" ] } } }
        ],
        "as": "matchedIngredients"
      }},
      { "$unwind": "$ingredients.matchedIngredients" },
      { "$group": {
        "_id": "$_id",
        "name": { "$first":"$name" },
        "cuisine": { "$first":"$cuisine" },
        "ingredients": { "$push":"$ingredients" }
      }}
    ],
    "as": "dietPlans.dietPlanCurrent.monday.breakfast.mealObject"
  }},
  { "$unwind": "$dietPlans.dietPlanCurrent.monday.breakfast.mealObject" }
])

关于javascript - $lookup 深度嵌套对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50971793/

有关javascript - $lookup 深度嵌套对象的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby-on-rails - 按天对 Mongoid 对象进行分组 - 2

    在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev

  3. ruby-on-rails - Rails 编辑表单不显示嵌套项 - 2

    我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib

  4. ruby - 将散列转换为嵌套散列 - 2

    这道题是thisquestion的逆题.给定一个散列,每个键都有一个数组,例如{[:a,:b,:c]=>1,[:a,:b,:d]=>2,[:a,:e]=>3,[:f]=>4,}将其转换为嵌套哈希的最佳方法是什么{:a=>{:b=>{:c=>1,:d=>2},:e=>3,},:f=>4,} 最佳答案 这是一个迭代的解决方案,递归的解决方案留给读者作为练习:defconvert(h={})ret={}h.eachdo|k,v|node=retk[0..-2].each{|x|node[x]||={};node=node[x]}node[

  5. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  6. Ruby 写入和读取对象到文件 - 2

    好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

  7. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  8. ruby-on-rails - 未在 Ruby 中初始化的对象 - 2

    我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调

  9. ruby - 如何在 Rails 4 中使用表单对象之前的验证回调? - 2

    我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser

  10. Ruby——嵌套类和子类是一回事吗? - 2

    下面例子中的Nested和Child有什么区别?是否只是同一事物的不同语法?classParentclassNested...endendclassChild 最佳答案 不,它们是不同的。嵌套:Computer之外的“Processor”类只能作为Computer::Processor访问。嵌套为内部类(namespace)提供上下文。对于ruby​​解释器Computer和Computer::Processor只是两个独立的类。classComputerclassProcessor#Tocreateanobjectforthisc

随机推荐