通过 Mongoose、Node.js、MongodB 中的特定属性查找嵌入式文档

Posted

技术标签:

【中文标题】通过 Mongoose、Node.js、MongodB 中的特定属性查找嵌入式文档【英文标题】:Finding an Embedded Document by a specific property in Mongoose, Node.js, MongodDB 【发布时间】:2011-08-11 23:50:16 【问题描述】:

对于这个应用程序,我使用的是 Node.js、MongoDB、Mongoose 和 Express

所以我有一个包含枢轴数组的参数对象,我想从枢轴中读取某些数据,如下所述

---in models.js-------------------------
    var Pivot = new Schema(
    value : String
  , destination : String
  , counter : Number
 );


var Param = new Schema(
    title : String
  , desc : String
  , pivots : [Pivot]
);


------------- in main.js --------------

var Param = db.model('Param');


app.get('/:title/:value', function(req, res)
    Param.findOne("title":req.param('title'), function(err, record)
           console.log(record.pivots);
           record.pivots.find("value":req.param('value'), function(err, m_pivot)
                    pivot.counter++;
                    res.redirect(m_pivot.destination);
           );
           record.save();
    );
);

我知道代码在 console.log(record.pivots) 之前一直有效,因为我得到了一个包含正确枢轴文档的文档集合。

但是,似乎没有一种查找方法可以让我通过架构中定义的“值”属性来匹配嵌入的文档。是否可以使用 .find() 或 .findOne() 搜索这个嵌入文档数组,如果没有,是否有一些简单的方法可以通过 mongoose 访问它?

【问题讨论】:

【参考方案1】:

我认为您正在寻找“$in”关键字?

如:

a: $in: [10, "hello"]

来源:MongoDB Queries CheatSheet

【讨论】:

我不这么认为 - $in 允许您在 a 值为 10 或 hello 的集合中搜索。这不是我在这里寻找的——对我来说,出于某种奇怪的原因,基本查询本身不起作用。【参考方案2】:

我暂时使用了一个简单的for循环来解析对象数组,如下:

for (var i=0; i <record.pivots.length; i++)
   if (record.pivots[i].value == req.param('value'))
      res.redirect(record.pivots.destination);
    

但是,我仍然认为 Mongoose 必须有一种更简单的方式与嵌入文档进行交互——而且这个循环有点慢,尤其是当嵌入文档的数量增长很大时。

如果有人对在 js 或 mongoose 函数中更快地搜索此对象数组的方法有任何建议,请在下面发布。

【讨论】:

【参考方案3】:

您可以像这样使用嵌入式文档属性进行查询:

'pivot.value': req.param('value')

根据评论更新:

app.get('/:title/:value', function(req, res) 
  Param.findOne('pivot.value': req.param('value'), "title":req.param('title'),
                function(err, record) 
                  record.pivot.counter++;
                  res.redirect(m_pivot.destination);  
                 record.save();
               );
);

【讨论】:

似乎不起作用,你能告诉我在我在 OP 中概述的代码中我应该在哪里调用它 在您的建议中,函数记录中有一个包含枢轴数组的参数。我仍然需要再次对枢轴进行分类以找到正确的。我希望能够获得指向正确枢轴的指针,以便我可以转到 URL。 另外,你的函数在使用的变量方面是错误的——“m_pivot”是我不使用的内部循环的变量。您将枢轴引用为record.pivot & m_pivot。我不明白您使用的结构 - record.pivot 不存在 - 查询返回带有 record.pivots 的记录,这是一个包含所有枢轴的数组,无论如何我都是用我的代码获得的。我想用 pivot.value = value 返回我需要的枢轴 @varunsrin 这对我不起作用。你让它工作了吗?谢谢【参考方案4】:

瓦伦斯林,

应该这样做

app.get('/:title/:value', function(req, res) 
  Param.findOne('pivots.value': req.param('value'), "title":req.param('title'),
                function(err, record) 
                  record.pivot.counter++;
                  res.redirect(m_pivot.destination);  
                 record.save();
               );
);

注意查询的复数形式以匹配架构中的字段名称

【讨论】:

【参考方案5】:

这样做的最大问题是,如果您的 req 有一些字段为空(应该充当通配符),您将找不到任何内容,因为 mongo 也尝试匹配空参数,因此搜索 "user":"bob ", "color":"" 与 "user":"bob", "color":"red" 或 "user":"bob" 不同。这意味着您必须首先创建一个查询对象并在传入之前过滤掉任何未使用的参数,并且如果您创建了一个查询对象,则不能再执行诸如“user.name = ...”之类的操作,因为mongo interperets这是一个错误,因为它不会首先将对象文字解析为字符串。 对这个问题有什么想法吗?

ps。您会认为制作如下对象很容易: 用户名=“鲍勃”;用户颜色:“绿色”; user.signup.time="12342561" 然后只使用用户作为查询对象:/

【讨论】:

以上是关于通过 Mongoose、Node.js、MongodB 中的特定属性查找嵌入式文档的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 mongo、passport 和 node js 更新用户的个人资料?

在 Node JS 中填充 Mongoose

Mongoose、Cygwin 和 MongoDB - 不保存

Mongoose、Cygwin 和 MongoDB - 不保存

Node.js/Mongoose 上的“版本错误:未找到匹配的文档”错误

与 mongoose/node.js 共享数据库连接参数的最佳方式