首页 > 解决方案 > Mongoose 获取有条件的字段

问题描述

我有这样的架构:

parentId: Number
name:[ 
       new Schema({
           language: { type: String, enum: ['en-US', 'fr-CA'] },
           text: String,
       },{ _id: false }
       );
     ],
isActive: Boolean
...

和如下示例数据:

{
  parentId:1,
  "name": [
            {"language": "en-US", "text": "Book"},
            {"language": "fr-CA", "text": "livre"}
          ],
   isActive:true
   // and so many other fields
},
{
  parentId:1,
  "name": [
            {"language": "en-US", "text": "Pen"}
          ],
   isActive:true
   // and so many other fields
}

我的猫鼬搜索法语文本:

db.langs.find({
  "name.language":"fr-CA", parentId: 1
})

Q1。我怎样才能像这样用法语返回名称:

{
  parentId:1,
  "name": "livre",
   isActive:true
   // and so many other fields
}

Q2。猫鼬有没有可能我可以返回法语文本,如果法语不存在,它会返回英语?

{
  parentId:1,
  "name": "livre",
   isActive:true
   // and so many other fields
},
{
  parentId:1,
  "name": "pen",
   isActive:true
   // and so many other fields
}

标签: javascriptnode.jsmongodbmongooseaggregation-framework

解决方案


问题一:

您可以使用它$unwind来解构数组并$match像一个对象一样。并且最少用所需的值$addFields覆盖name字段(如果有多个字段比使用更好的选择$project)。所有这些都在这样的聚合管道中:

db.collection.aggregate([
  {
    "$match": {
      "parentId": 1
    }
  },
  {
    "$unwind": "$name"
  },
  {
    "$match": {
      "name.language": "fr-CA"
    }
  },
  {
    "$addFields": {
      "name": "$name.text"
    }
  }
])

这里的例子

问题2:

您可以使用$facet创建“两种方式”。如果存在法语结果,则一个,如果不存在,则另一个。然后检查是否存在以输出一个值或另一个值,如下所示:

db.collection.aggregate([
  {
    "$match": {
      "parentId": 1
    }
  },
  {
    "$unwind": "$name"
  },
  {
    "$facet": {
      "french": [
        {
          "$match": {
            "name.language": "fr-CA"
          }
        }
      ],
      "notFrench": [
        {
          "$match": {
            "name.language": "en-US"
          }
        }
      ]
    }
  },
  {
    "$project": {
      "result": {
        "$cond": {
          "if": {
            "$eq": [
              {
                "$size": "$french"
              },
              0
            ]
          },
          "then": "$notFrench",
          "else": "$french"
        }
      }
    }
  }
])

这里的例子


推荐阅读