Node.js 查找MongoDb模式设计的查询

Node.js 查找MongoDb模式设计的查询,node.js,mongodb,mongoose,mongodb-query,Node.js,Mongodb,Mongoose,Mongodb Query,我有一个厨房模式,它的结构如下,我想在这个模式上做一个find查询,从packages数组中得到一个具有特定ID和日期的包 { "_id" : ObjectId("58aacd498caf670a837e7093"), "name" : "Kitchen 1", "packages" : [ { "package" : ObjectId("58aacd038caf670a837e7091"), "availibility" : [

我有一个厨房模式,它的结构如下,我想在这个模式上做一个find查询,从packages数组中得到一个具有特定ID和日期的包

{
"_id" : ObjectId("58aacd498caf670a837e7093"),
"name" : "Kitchen 1",
"packages" : [ 
    {
        "package" : ObjectId("58aacd038caf670a837e7091"),
        "availibility" : [ 
            {
                "date" : ISODate("2015-03-25T00:00:00.000Z"),
                "count" : 20
            }, 
            {
                "date" : ISODate("2016-03-25T00:00:00.000Z"),
                "count" : 30
            }
        ]
    }, 
    {
        "package" : ObjectId("58aacd108caf670a837e7092"),
        "availibility" : [ 
            {
                "date" : ISODate("2016-03-25T00:00:00.000Z"),
                "count" : 10
            }
        ]
    }
],
"__v" : 0
}
如果我使用包ID(58aacd038caf670a837e7091)和日期(2015-03-25T00:00:00.000Z)执行查找查询,则响应应该如下所示:-

{
 "package" : ObjectId("58aacd038caf670a837e7091"),
 "date" : ISODate("2015-03-25T00:00:00.000Z")
 "count" : 20
}
在mongodb中:

您必须使用循环才能只看到一个日期。对于所有日期,包括包id的匹配日期,您可以执行以下操作:

db.collection_name.find({'packages.package':ObjectId("package_id"),'packages.availability.date': ISODate("date")},{'packages.package':1, 'packages.availability':1}).pretty()
在mongoose中,我假设您已经导入了厨房模式

Kichen.find({'packages.package':"package_id",'packages.availability.date': "iso_date"}, function(err, package){
   if(err) 
       console.log("There was an error");
   if(package == null){
       console.log("no package found");
   } else {
       //do whatever
   }
});
在mongodb中:

您必须使用循环才能只看到一个日期。对于所有日期,包括包id的匹配日期,您可以执行以下操作:

db.collection_name.find({'packages.package':ObjectId("package_id"),'packages.availability.date': ISODate("date")},{'packages.package':1, 'packages.availability':1}).pretty()
在mongoose中,我假设您已经导入了厨房模式

Kichen.find({'packages.package':"package_id",'packages.availability.date': "iso_date"}, function(err, package){
   if(err) 
       console.log("There was an error");
   if(package == null){
       console.log("no package found");
   } else {
       //do whatever
   }
});

您可以比较循环中的值:

db.so.find().forEach(function(po){
  po.packages.forEach(function(co){
    co.availibility.forEach(function(o){
      if(co.package=='58aacd038caf670a837e7091' 
        &&
        String(ISODate("2015-03-25T00:00:00.000Z"))==String(o.date)
      ){
        o.package=co.package;
        printjson(o);
      }
    })
  })
});
{
        "date" : ISODate("2015-03-25T00:00:00Z"),
        "count" : 20,
        "package" : ObjectId("58aacd038caf670a837e7091")
}

您可以比较循环中的值:

db.so.find().forEach(function(po){
  po.packages.forEach(function(co){
    co.availibility.forEach(function(o){
      if(co.package=='58aacd038caf670a837e7091' 
        &&
        String(ISODate("2015-03-25T00:00:00.000Z"))==String(o.date)
      ){
        o.package=co.package;
        printjson(o);
      }
    })
  })
});
{
        "date" : ISODate("2015-03-25T00:00:00Z"),
        "count" : 20,
        "package" : ObjectId("58aacd038caf670a837e7091")
}

您可以运行聚合操作,使用运算符在两个管道步骤内返回所需字段

考虑以下管道:

Kitchen.aggregate([
    {
        "$project": {
            "packages": {
                "$arrayElemAt": [
                    {
                        "$filter": {
                            "input": "$packages",
                            "as": "pkg",
                            "cond": {
                                "$eq": [
                                    "$$pkg.package", 
                                    mongoose.Types.ObjectId("58aacd038caf670a837e7091")
                                ]
                            } 
                        }
                    },
                    0
                ]
            }
        }
    },
    {
        "$project": {
            "package": "$packages.package",
            "availibility": {
                "$arrayElemAt": [
                    {
                        "$filter": {
                            "input": "$packages.availibility",
                            "as": "el",
                            "cond": {
                                "$eq": ["$$el.date", new Date("2015-03-25")]
                            } 
                        }
                    },
                    0
                ]
            }
        }
    },
    {
        "$project": {
            "_id": 0,
            "package": 1,
            "date": "$availibility.date",
            "count": "$availibility.count"
        }
    }
]).exec(function(err, docs){
    if (err) throw err;
    console.log(docs);
})

您可以运行聚合操作,使用运算符在两个管道步骤内返回所需字段

考虑以下管道:

Kitchen.aggregate([
    {
        "$project": {
            "packages": {
                "$arrayElemAt": [
                    {
                        "$filter": {
                            "input": "$packages",
                            "as": "pkg",
                            "cond": {
                                "$eq": [
                                    "$$pkg.package", 
                                    mongoose.Types.ObjectId("58aacd038caf670a837e7091")
                                ]
                            } 
                        }
                    },
                    0
                ]
            }
        }
    },
    {
        "$project": {
            "package": "$packages.package",
            "availibility": {
                "$arrayElemAt": [
                    {
                        "$filter": {
                            "input": "$packages.availibility",
                            "as": "el",
                            "cond": {
                                "$eq": ["$$el.date", new Date("2015-03-25")]
                            } 
                        }
                    },
                    0
                ]
            }
        }
    },
    {
        "$project": {
            "_id": 0,
            "package": 1,
            "date": "$availibility.date",
            "count": "$availibility.count"
        }
    }
]).exec(function(err, docs){
    if (err) throw err;
    console.log(docs);
})

您可以添加,预期结果。我已经添加了结果结构您的MongoDB服务器版本是什么?@chridam version-3.4.1您可以添加,预期结果。我已经添加了结果结构MongoDB服务器版本是什么?@chridam version-3.4.1您指定了
packages.package':1
,而我猜OP要求查找数组indexit更容易使用mongoose,然后在结果中循环。。。使用直接的mongodb会很困难,而且很容易出错指定
包。包:1
,而我猜OP要求查找数组indexit更容易使用mongoose,然后循环遍历结果。。。直接使用mongodb会很困难,而且容易出错