Mongoose用多个参数搜索FindOne

时间:2013-09-19 00:37:52

标签: node.js mongodb angularjs mongoose

我第一次尝试使用Angular + express + mongodb构建一些东西,所以我可能完全以错误的方式解决这个问题。 Express被用来提供json。然后Angular负责所有的观点等。

我正在使用Mongoose与Mongo进行互动。

我有以下数据库架构:

var categorySchema = new mongoose.Schema({
  title: String, // this is the Category title
  retailers : [ 
    {
      title: String,  // this is the retailer title
      data: {       // this is the retailers Data
        strapLine: String,
        img: String ,  // this is the retailer's image
        intro: String,
        website: String,
        address: String,
        tel: String,
        email: String
      } 
    }
  ]
});

var Category = mongoose.model('Category', categorySchema);

在Express中我有几条获取数据的路线:

 app.get('/data/categories', function(req, res) {
   // Find all Categories.
   Category.find(function(err, data) {
     if (err) return console.error(err);
     res.json(data)
   });
 });


 // return a list of retailers belonging to the category
 app.get('/data/retailer_list/:category', function(req, res) {
   //pass in the category param (the unique ID), and use that to do our retailer lookup
   Category.findOne({ _id: req.params.category }, function(err, data) {
     if (err) return console.error(err);
     res.json(data)
   }); 
 });

上述工作 - 我只是在试图进入一家零售商时遇到大问题。我正在通过这个类别和零售商ID ...我已经尝试了各种各样的事情 - 从对类别进行查找,然后对内容中的findOne进行...但我不能让它工作。我可能会这样做错了......

我在这里找到了这个帖子:findOne Subdocument in Mongoose并实施了解决方案 - 但是,它会返回我所有的零售商 - 而不仅仅是我想要的零售商。

// Returns a single retailer
app.get('/data/retailer_detail/:category/:id', function(req, res) {
  //pass in the category param (the unique ID), and use that to do our retailer lookup
 Category.findOne({_id: req.params.category , 'retailers.$': 1}, function(err, data) {
    console.log(data);
    if (err) return console.error(err);
    res.json(data)
  }); 
});    

谢谢, 罗布

2 个答案:

答案 0 :(得分:9)

现在我看到了您的完整过滤器/查询,您应该能够在这种情况下使用array positional operator作为投影的一部分,而不是进行客户端过滤:

app.get('/data/retailer_detail/:category/:id', function(req, res) {
  //pass in the category param (the unique ID), and use that to do our retailer lookup
 Category.findOne({
    /* query */
    _id: req.params.category , 
    'retailers._id' : req.params.id
  },
  {  /* projection */
     "retailers.$" : 1 
  }, 
  function(err, data) {
  var retailer = _.where(data.retailers , { id : req.params.id });
    if (err) return console.error(err);
    res.json(retailer)
  }); 
}); 

要使{ "retailers.$" : 1 }正常工作,查询必须包含数组中元素的字段。 $运算符仅返回第一个匹配项。

答案 1 :(得分:1)

隔壁的人使用Mongo + Express并给了我一些指示:他们向我解释了mongo是如何工作的,并建议我应该使用underscore.js协助我的过滤器。

他们说我需要将整个类别拉出来 - 然后运行过滤器。我并不严格需要'retailers._id':req.params.id}但是他们说要保留它,因为它保证只有当其中的项目包含该信息时才会返回该类别。我仍然不知道为什么或如何...所以不能真正标记这个解决..它解决了,但我真的不明白为什么 - 所以会做更多的阅读:)

app.get('/data/retailer_detail/:category/:id', function(req, res) {
  //pass in the category param (the unique ID), and use that to do our retailer lookup
 Category.findOne({_id: req.params.category , 'retailers._id' : req.params.id}, function(err, data) {
  var retailer = _.where(data.retailers , { id : req.params.id });
    if (err) return console.error(err);
    res.json(retailer)
  }); 
});