如何在不使用 _id 字段但使用多个属性的情况下在 mongoose 中查找子文档

Posted

技术标签:

【中文标题】如何在不使用 _id 字段但使用多个属性的情况下在 mongoose 中查找子文档【英文标题】:How to find a sub document in mongoose without using _id fields but using multiple properties 【发布时间】:2015-05-19 02:58:08 【问题描述】:

我有一个这样的示例架构 -

Comment.add(
    text:String,
    url:type:String,unique:true,
    username:String,
    timestamp:type:Date,default:Date
);
Feed.add(
    url:type:String, unique:true ,
    username:String,
    message:type:String,required:'PATH is required!',
    comments:[Comment],
    timestamp:type:Date,default:Date
);

现在,我不想将 _id 字段暴露给外界,这就是为什么我不会将它发送给任何地方的客户。 现在,我的评论模式中有两个重要的属性(用户名、网址) 我要做的是更新满足的子文档的内容

    feed.url comment.url comment.username

如果comment.username 与我的客户端值req.user.username 相同,则更新该记录的comment.text 属性,该记录的URL 由客户端在req.body.url 变量中提供。

我认为一种耗时的方法是首先找到具有给定 url 的提要,然后遍历所有子文档以找到满足 comment.url==req.body.url 的文档,然后检查 comment.username==req.user.username 是否满足,如果是,则更新评论对象。 但是,我认为必须有一种更简单的方法来做到这一点? 我已经试过了——

db.feeds.update("username":"harshitladdha93@gmail.com","comments.username":"harshitladdha3@gmail.com","comments.url":"test",$set:"comments.$.text":"updated text 2")

从http://www.tagwith.com/question_305575_how-to-find-and-update-subdocument-within-array-based-on-parent-property找到

但即使comments.urlcomments.username与其他子文档匹配,也会更新

我也试过了

db.feeds.distinct("comments._id","comments.url":req.body.url)

查找与url 关联的文档的_id,但它返回子文档中的所有_id

【问题讨论】:

【参考方案1】:

首先 - 在安全性方面,您不应该依赖 _id 不被外界看到。这是一个非常糟糕的主意,原因有很多(主要是 REST,而且默认情况下它会随您的所有查询返回)。

现在,为了解决您的问题,您需要的是 $elemMatch 运算符。这表示您正在寻找数组中指定的子文档与多个查询匹配的内容。

例如

db.feeds.update(
    "username":"harshitladdha93@gmail.com",
    comments: 
        $elemMatch: 
            username: "harshitladdha3@gmail.com",
            url: "test"
        
    
, $set: "comments.$.text":"updated text 2")

如果您不使用$elemMatch,您的意思是如果有任何 cmets 与您的查询匹配 - 即如果用户“harshitladdha3@gmail.com”有评论,那么您对文档没问题,并且单独的评论有一个url“test”,除非你使用$elemMatch,否则文档将匹配

【讨论】:

以上是关于如何在不使用 _id 字段但使用多个属性的情况下在 mongoose 中查找子文档的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用临时表或视图的情况下在多个列上使用 PIVOT [重复]

如何在不复制的情况下在多个进程中使用大型数据集?

如何在不使用模拟位置的情况下在 android 上欺骗位置?

如何在不使用存储过程的情况下在表函数中返回值 exec?

如何在不将其添加到目录的情况下在多个团队中安装机器人?

如何在不使用边框间距和空行的情况下在带有边框的表格行之间添加空格