选择匹配的数组元素并返回所选字段 [英] Select Matching Array Element and Return Selected Fields

查看:99
本文介绍了选择匹配的数组元素并返回所选字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道如何从Mongoose查询中为匹配的对象数组设置投影.

I would like to know how to set the projection for a matched array of objects from a Mongoose query.

例如,如果我有一个看起来像这样的猫鼬模型:

For example, if I have a Mongoose model that looks something like this:

var User = new Schema({
  name: String,
  children: [Child]
});

var Child = new Schema({
  name: String,
  height: Number,
  age: Number,
  secret: Number
});

换句话说,此模型可能会产生一个示例JSON对象:

In other words, an example JSON object that might result from this model:

User: {
  name: 'abc',
  children: [
    {
      name: 'def',
      height: 123,
      age: 7,
      secret: 2
    },
    {
      name: 'ghi',
      height: 456,
      age: 9,
      secret: 3
    }
  ]
}

如您所见,模型包含属性children,该属性是Child个对象的数组.

As you can see the model contains a property children that is an array of Child objects.

如果我仅匹配User,其中User包含children中具有属性name: 'def'的项目:

If I match only User that contain an item in children that has property name: 'def':

Users.find({
  children.name: 'def'
})

然后我可以使用位置运算符($)设置投影以选择属性(例如name)以及匹配对象的属性:

I can then set the projection to select properties (such as name) and also properties from the matched object using a positional operator ($):

.select({
  name: 1,
  children.$: 1
}

现在的问题是,使用这种投影,children.$将始终返回整个Child对象,包括我可能不想查询的属性,例如secret.

The problem now is that with this projection, children.$ will always return the entire Child object, including properties I may not want to query, such as secret.

{
  name: 'abc',
  children: [
    {
      name: 'def',
      height: 123,
      age: 7,
      secret: 2
    }
  ]
}

理想情况下,我希望也可以从通过$获取的child对象中选择某些属性,类似于从父对象User中选择name的方式,但是我找不到解决方法这个.

Ideally I would like to be able to also select certain properties from the child object obtained through $ similar to how name was selected from the parent object User, but I cannot find a way to do this.

选择单个属性的一种方法是使用格式children.$.age,但这只能用于选择1个属性,因为多次执行会导致错误,因为您无法多次使用正向$运算符

One way to select a single property is to use the format children.$.age but this can only be used to select 1 property, as doing it multiple times results in an error as you cannot use the poisitional $ operator multiple times.

.select({
  name: 1,

  // and now select the height and age
  // but only of the child that matches name = 'def'
  // WITHOUT returning the entire object (exclude name and secret)
  children.$.age,
  children.$.height // error
})

是否可以在猫鼬中为位置运算符选择的对象选择投影?

Is selecting the projection for an object obtained by the positional operator possible in Mongoose?

推荐答案

如果您只想选择要返回的数组的某些字段,那么您正在谈论的是重塑"文档.对于基本"字段选择以外的任何内容,这意味着将 .aggregate() 用作该方法代替 .find() .

If you want to only select certain fields of an array to return then you are talking about "reshaping" the document. For anything beyond "basic" field selection, this means using .aggregate() as the method instead of .find().

所以这里的两个要求是 $filter 对数组内容进行匹配"并返回,以及 $map 数组本身的实际返回字段":

So the two requirements here are to $filter on the array content to "match" and return, as well as $map the actual "fields to return" from the array itself:

User.aggregate([
  { "$match": { "children.name": "def" } },
  { "$project": {
     "name": 1,
     "children": {
       "$map": {
         "input": {
           "$filter": {
             "input": "$children",
             "as": "c",
             "cond": { "$eq": [ "$$c.name", "def" ] } 
           }
         },
         "as": "c",
         "in": {
           "age": "$$c.age",
           "height": "$$c.height"
         }
       }
     }
  }}
])

此处使用 $filter 来减少数组中的内容只包括那些与条件匹配的内容.具有与值"def"相同的"name"属性的那些.然后将其作为"input"参数传递给 $map .

Here $filter is used in order to reduce the contents of the array down to only those that match the condition. Being those that have the same "name" property as the value "def". This is then passed as the "input" parameter to $map.

$map 运算符的工作方式与其他语言的对应语言,因为它重塑数组"以根据您在"in"参数中指定的内容返回某些内容.因此,在这里,我们实际上仅显式地命名属性,并在其中为正在处理的当前数组元素使用变量分配,以使这些赋值作为新"数组内容返回.

The $map operator works just like it's other language counterparts in that it "reshapes arrays" to return something according to what you specify in the "in" parameter. So here we actually only explicitly name the properties and use there variable assignments for the current array element being processed so that these are what are returned as the "new" array content.

总体结果是一个数组,其中包含:

The overall result is an array, containing:

  1. 符合指定条件的物品.
  2. 只是指定要返回的字段.

这篇关于选择匹配的数组元素并返回所选字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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