是否可以在具有$ elemMatch投影的同一集合上使用查询投影? [英] Is It possible to use query projection on the same collection that has a $elemMatch projection?

查看:71
本文介绍了是否可以在具有$ elemMatch投影的同一集合上使用查询投影?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我了解您可以使用 $ elemMatch限制子集合数组中的项目作为投影.这样使用时,无论

I understand that you can limit the items in a subcollection array using $elemMatch as a projection. When using it as such it returns all fields of the subdocuments that match regardless if query projections are also specified.

是否可以限制匹配的子文档中返回的字段?你会怎么做?

Is it possible to limit the fields returned in the matching subdocuments? How would you do so?

使用版本3.8.9.

给出简单的模式:

var CommentSchema = mongoose.Schema({
  body: String,
  created: {
    by: {
      type: String,
      required: true
    },
    date: {
      type: Date,
      default: Date.now
    }
  }
});

var BlogSchema = mongoose.Schema({
  title: String,
  blog: String,
  created: {
    by: {
      type: String,
      required: true
    },
    date: {
      type: Date,
      default: Date.now
    }
  },
  comments: [CommentSchema]
});

var Blog = mongoose.model('Blog',modelSchema);

示例

Blog.findOne({_id: id}, {_id: 1, comments: {$elemMatch: {'created.by': 'Jane'}, body: 1}}, function(err, blog) {
  console.log(blog.toJSON());
});
// outputs:
{
  _id: 532cb63e25e4ad524ba17102,
  comments: [
    _id: 53757456d9c99f00009cdb5b,
    body: 'My awesome comment',
    created: { by: 'Jane', date: Fri Mar 21 2014 20:34:45 GMT-0400 (EDT) }
  ]
}

// DESIRED OUTPUT
{
  _id: 532cb63e25e4ad524ba17102,
  comments: [
    body: 'My awesome comment'
  ]
}

推荐答案

是的,有两种方法可以做到这一点.因此,您可以使用 $elemMatch 与投影端一样,稍有变化:

Yes there are two ways to do this. So you can either use the $elemMatch on the projection side as you already have, with slight changes:

Model.findById(id,
   { "comments": { "$elemMatch": {"created.by": "Jane" } } },
   function(err,doc) {

或仅添加到查询部分并使用位置$运算符:

Or just add to the query portion and use the positional $ operator:

Model.findOne(
    { "_id": id, "comments.created.by": "Jane" },
    { "comments.$": 1 },
    function(err,doc) {

这两种方法都是完全有效的.

Either way is perfectly valid.

如果您需要更多相关内容,可以使用 $project 运算符:

If you wanted something a little more involved than that, you can use the .aggregate() method and it's $project operator instead:

Model.aggregate([
    // Still match the document
    { "$match": "_id": id, "comments.created.by": "Jane" },

    // Unwind the array
    { "$unwind": "$comments" },

    // Only match elements, there can be more than 1
    { "$match": "_id": id, "comments.created.by": "Jane" },

    // Project only what you want
    { "$project": {
        "comments": {
            "body": "$comments.body",
            "by": "$comments.created.by"
        }
    }},

    // Group back each document with the array if you want to
    { "$group": {
        "_id": "$_id",
        "comments": { "$push": "$comments" }
    }}
],
function(err,result) {

因此,聚合框架可用于的功能远不止是简单地聚合结果.它是 $project 运算符为您提供的比使用.find()进行投影所提供的灵活性更高.它还允许您过滤并返回多个数组结果,这也是.find()中的投影无法做到的.

So the aggregation framework can be used for a lot more than simply aggregating results. It's $project operator gives you more flexibility than is available to projection using .find(). It also allows you to filter and return multiple array results, which is also something that cannot be done with projection in .find().

这篇关于是否可以在具有$ elemMatch投影的同一集合上使用查询投影?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆