草庐IT

node.js - Mongoose 用条件填充子文档并更新它们

coder 2023-11-05 原文

我在更新 UserModel 子文档时遇到问题,该子文档是 (OfferModel)

const user = Schema({
  name: String,
  offers: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Offer'
  }]
});

const offer = Schema({
  title: String,
  post: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Post'
  },
  buyer: {
    deal: String,
    user: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'User'
    }
  },
  seller: {
    deal: String,
    user: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'User'
    }
  }
});

情况是这样的 我有一个用户在 1 个帖子上有 3 个优惠,但总共有 10 个优惠

Post A = 3 offers.
Post B = 7 offers.

然后我在帖子A上接受了一个报价,所以我查询数据库并将“买家”下的“交易”属性设置为“确定”,这没有问题。现在我需要将“拒绝”设置为 Post A 上的其他 2 个报价。 如果我使用 Javascript 方式,则有一个解决方案:

  1. 获取帖子 ID
  2. 在用户模型下填充报价,使用匹配运算符仅获取特定帖子上的报价以及尚未确认的报价(即 2 个报价)
  3. 遍历它们并分配 user.offers.buyer.deal = "rejected"
  4. 保存()

用这种方法没问题,但我想用 Mongoose 的方式来做,我只想知道如何用 Mongoose 的方式来做?

我还检查了 .update() 运算符,但我似乎无法使其正常工作,或者这不是我需要的东西。

关于如何仅使用 Mongoose 运算符更新这 2 个报价的任何输入?

谢谢

**更新

const user = await this.userRepo.findUser(req.user._id)
  .select('offers')
  .populate({
    path: 'offers',
    match: {
      post: req.body.postId,
      'buyer.feedback': 'none'
    }
  })
  .update({}, {
    '$set': {
      'offers.$.buyer.feedback': 'ok'
    }
  });

错误 CastError:转换为 ObjectId 失败,因为路径“offers”中的值“ok”

***更新 2 个示例文档 ****更新3前后

// John
{
  "_id": ObjectId("5abf3c2fb9709a31244ee2a8"),
  "name": "john",
  "offers": [
    ObjectId("5ad2aac1b0ef21131439223c"), // Offer that i accepted
    ObjectId("5ad2ab39b0ef21131439223d"), // Offer i should reject
    ObjectId("5ad2b9b2751c39321c4173e4"), // Offer i should reject
    ObjectId("5ad2d0846778d91eb0b109a8"),
    ObjectId("5ad2d136e50e903240cdb4b9"),
    ObjectId("5ad2d14ae50e903240cdb4ba"),
    ObjectId("5ad2d2acde95b51e205b26fc"),
    ObjectId("5ad9cbaec9c10314148adcd8"),
    ObjectId("5ad9ccf60c7f492940d4bd9d"),
    ObjectId("5ad9cd2e0c7f492940d4bd9e"),
  ],
  "post": [
    ObjectId("5abf4eb433063a3ebc8ba78f"), // Post A
    ObjectId("5abf4ec533063a3ebc8ba790"),
  ]
};

// Offer that i accepted
{
  "_id" : ObjectId("5ad2aac1b0ef21131439223c"),
    "buyer" : {
      "deal" : "ok",
      "feedback" : "none",
      "user" : ObjectId("5abf3c2fb9709a31244ee2a8")
  },
  "seller" : {
    "deal" : "none",
    "feedback" : "none",
    "user" : ObjectId("5abf3c2fb9709a31244ee8bf")
  },
  "post" : ObjectId("5abf4eb433063a3ebc8ba78f"),
}

// (BEFORE) Offer that i should reject
[{
  "_id" : ObjectId("5ad2ab39b0ef21131439223d"),
  "buyer" : {
    "deal" : "none",
    "feedback" : "none",
    "user" : ObjectId("5abf3c2fb9709a31244ee2a8")
  },
  "seller" : {
    "deal" : "none",
    "feedback" : "none",
    "user" : ObjectId("5abf3c2fb9709a31244ee8bd")
  },
  "post" : ObjectId("5abf4eb433063a3ebc8ba78f"),
},
{
  "_id": ObjectId("5ad2b9b2751c39321c4173e4"),
  "buyer": {
    "deal": "none",
    "feedback": "none",
    "user": ObjectId("5abf3c2fb9709a31244ee2a8")
    },
  "seller": {
    "deal": "none",
    "feedback": "none",
    "user": ObjectId("5abf3c2fb9709a31244ee8aa")
    },
  "post": ObjectId("5abf4eb433063a3ebc8ba78f"),
}]

// (AFTER)
[{
  "_id": ObjectId("5ad2ab39b0ef21131439223d"),
  "buyer": {
    "deal": "rejected",
    "feedback": "none",
    "user": ObjectId("5abf3c2fb9709a31244ee2a8")
  },
  "seller": {
    "deal": "none",
    "feedback": "none",
    "user": ObjectId("5abf3c2fb9709a31244ee8bd")
  },
  "post": ObjectId("5abf4eb433063a3ebc8ba78f"),
},
  {
    "_id": ObjectId("5ad2b9b2751c39321c4173e4"),
    "buyer": {
      "deal": "rejected",
      "feedback": "none",
      "user": ObjectId("5abf3c2fb9709a31244ee2a8")
    },
    "seller": {
      "deal": "none",
      "feedback": "none",
      "user": ObjectId("5abf3c2fb9709a31244ee8aa")
    },
    "post": ObjectId("5abf4eb433063a3ebc8ba78f"),
  }]

最佳答案

你应该试试这样的东西

Offers.update({
  "buyer.feedback": "none",  
  post: req.body.postId      //query
}, {
  '$set': {
    'buyer.feedback': 'ok'    // update operation
  }
})

关于node.js - Mongoose 用条件填充子文档并更新它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50422098/

有关node.js - Mongoose 用条件填充子文档并更新它们的更多相关文章

  1. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  2. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  3. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  4. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  5. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  6. ruby - 定义方法参数的条件 - 2

    我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano

  7. ruby - 匹配大写字母并用后续字母填充,直到一定的字符串长度 - 2

    我有一个驼峰式字符串,例如:JustAString。我想按照以下规则形成长度为4的字符串:抓取所有大写字母;如果超过4个大写字母,只保留前4个;如果少于4个大写字母,则将最后大写字母后的字母大写并添加字母,直到长度变为4。以下是可能发生的3种情况:ThisIsMyString将产生TIMS(大写字母);ThisIsOneVeryLongString将产生TIOV(前4个大写字母);MyString将生成MSTR(大写字母+tr大写)。我设法用这个片段解决了前两种情况:str.scan(/[A-Z]/).first(4).join但是,我不太确定如何最好地修改上面的代码片段以处理最后一种

  8. ruby-on-rails - 在 heroku 的 .fonts 文件夹中包含自定义字体,似乎无法识别它们 - 2

    Heroku支持人员告诉我,为了在我的Web应用程序中使用自定义字体(未安装在系统中,您可以在bash控制台中使用fc-list查看已安装的字体)我必须部署一个包含所有字体的.fonts文件夹里面的字体。问题是我不知道该怎么做。我的意思是,我不知道文件名是否必须遵循heroku的任何特殊模式,或者我必须在我的代码中做一些事情来考虑这种字体,或者如果我将它包含在文件夹中它是自动的......事实是,我尝试以不同的方式更改字体的文件名,但根本没有使用该字体。为了提供更多详细信息,我们使用字体的过程是将PDF转换为图像,更具体地说,使用rghostgem。并且最终图像根本不使用自定义字体。在

  9. objective-c - 在设置 Cocoa Pods 和安装 Ruby 更新时出错 - 2

    我正在尝试为我的iOS应用程序设置cocoapods但是当我执行命令时:sudogemupdate--system我收到错误消息:当前已安装最新版本。中止。当我进入cocoapods的下一步时:sudogeminstallcocoapods我在MacOS10.8.5上遇到错误:ERROR:Errorinstallingcocoapods:cocoapods-trunkrequiresRubyversion>=2.0.0.我在MacOS10.9.4上尝试了同样的操作,但出现错误:ERROR:Couldnotfindavalidgem'cocoapods'(>=0),hereiswhy:U

  10. ruby-on-rails - 使用包含多个关联和单独的条件 - 2

    我的Gallery模型中有以下查询:media_items.includes(:photo,:video).rank(:position_in_gallery)我的图库模型有_许多媒体项,每个都有一个照片或视频关联。到目前为止,一切正常。它返回所有media_items包括它们的photo或video关联,由media_item的position_in_gallery属性排序。但是我现在需要将此查询返回的照片限制为仅具有is_processing属性的照片,即nil。是否可以进行相同的查询,但条件是返回的照片等同于:.where(photo:'photo.is_processingIS

随机推荐