MongoDB嵌套查询结构

时间:2017-10-16 05:53:57

标签: mongodb mongodb-query

我的收藏中有以下json文档:

{
    "_id": {
        "$oid": "59e3a593734d1d62dcbe79c3"
    }
    "name": "UserNameKiran"
    "notebooks": [
        {
            "notebookname": "notebook1",
            "notes": [
                {
                    "name": "noteName"
                },
                {
                    "name": "noteName2"
                }
            ]
        },
        {
            "access": "public",
            "notebookname": "notebook2",
            "notes": [
                {
                    "name": "noteName"
                },
                {
                    "name": "noteName2"
                }
            ]
        }
    ]
};

我想从特定用户和笔记本中检索所有“笔记”。 例如:“notebook1”的所有注释。

我尝试了以下命令,但无法获得任何结果。

 req.db.collection('usernotecollection').find({
      "_id": ObjectId(req.params.userId),
      "notebooks": {
          "$elemMatch": {
              "notebookname": "notebook1"
          }
      }
    }, {notes:1}).toArray(function (err, results) {
        console.log(results);
  });

它只是将object_id返回给我,结果中没有其他内容。我错过了什么?

2 个答案:

答案 0 :(得分:0)

您为find()电话提供的第二个参数是:{notes:1}

这是一个投影,它告诉MongoDB返回名为notes的属性,但文档中有 no 属性名为notes,因此投影仅返回默认属性:_id

也许您打算在{notebooks:1}投射?虽然这会返回所有内容,因此在功能上等同于不提供投影。

为清楚起见,您可以运行以下命令,并且您会看到它们都返回相同的响应:

 req.db.collection('usernotecollection').find({
      "_id": ObjectId(req.params.userId),
      "notebooks": {
          "$elemMatch": {
              "notebookname": "notebook1"
          }
      }
    }).toArray(function (err, results) {
        console.log(results);
  });

 req.db.collection('usernotecollection').find({
      "_id": ObjectId(req.params.userId),
      "notebooks": {
          "$elemMatch": {
              "notebookname": "notebook1"
          }
      }
    }, {notebooks:1}).toArray(function (err, results) {
        console.log(results);
  });

但是,如果您真正想要的是具有notes子文档的notebooks属性,那么您将要'notebooks.notes': 1投影。以下示例在notebooks.notes上投影,并排除了默认的_id投影,因此仅返回notebooks.notes

 req.db.collection('usernotecollection').find({
      "_id": ObjectId(req.params.userId),
      "notebooks": {
          "$elemMatch": {
              "notebookname": "notebook1"
          }
      }
    }, {'notebooks.notes':1, '_id': 0}).toArray(function (err, results) {
        console.log(results);
  });

答案 1 :(得分:0)

为了过滤数组元素,您可以在查询的投影部分使用$elemMatch运算符。

req.db.collection('usernotecollection').find({
    // filter
    "_id": ObjectId(req.params.userId)
}, {
    // projection
    "notebooks": {
        "$elemMatch": {
            "notebookname": "notebook1"
        }
    }
}).toArray(function (err, results) {
    console.log(results);
});