开发者

Finding an Embedded Document by a specific property in Mongoose, Node.js, MongodDB

开发者 https://www.devze.com 2023-02-28 05:05 出处:网络
For this app, I\'m using Node.js, MongoDB, Mongoose & Express So I have a Param Object that contains an array of Pivots, and I want to read certain data from the pivots as outlined below

For this app, I'm using Node.js, MongoDB, Mongoose & Express

So I have a Param Object that contains an array of Pivots, and I want to read certain data from the pivots as outlined below

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


var Param = new Schema({
    title : String
  , desc : 开发者_Python百科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();
    });
});

I know that the code works until console.log(record.pivots), since i got a doc collection with the right pivot documents inside.

However, there does not seem to be a find method to let me match an embedded document by the 'value' property defined in the schema. Is it possible to search through this array of embedded documents using .find() or .findOne() , and if not, is there some easy way to access it through mongoose?


varunsrin,

This should do it

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();
               });
});

Note the pluralization of the query to match the field name in your schema


You can querying using embedded document properties like this:

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

Update in response to comment:

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();
               });
});


I solved it temporarily using a simple for loop to parse the object array as follows:

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

However, I still think that Mongoose must have a simpler way of interacting with embedded documents - and this loop is somewhat slow, especially when the number of embedded documents grows large.

If anyone has any suggestions for a faster way to search this object array either in js or with a mongoose function, please post below.


the biggest problem with this is that if your req has some fields empty (that should act as wildcard), you will not find anything since mongo tries to match empty params as well, so searching for {"user":"bob", "color":""} is not the same as {"user":"bob", "color":"red"} or {"user":"bob"}. this means that you have to first create a query object and filter out any unused parameters before you pass it in, and if you create a query object, you can no longer do something like "user.name=..." because mongo interperets this as an error since it does not first resolve the object literal into a string. Any ideas on this problem?

ps. You'd think it would be easy enough to make an object like: user.name="bob"; user.color:"green"; user.signup.time="12342561" and then just use user as a query object :/


I think you are looking for the "$in" keyword?

As in:

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

source: MongoDB Queries CheatSheet

0

精彩评论

暂无评论...
验证码 换一张
取 消