如果 MongoDB 文档具有特定字段,如何仅投影对象?

huangapple go评论63阅读模式
英文:

How can I project an object only if document has a specific field in MongoDB?

问题

I have the following project:

{
    "$project": {
        "_id": 1,
        "applicationIds": {
            "type": "linux",
            "refId": "$applicationIds"
        },
        "configurationIds": {
            "type": "linux",
            "refId": "$configurationIds"
        }
    }
}

只要$configurationIds至少有一条记录,我会得到类似于以下内容:

{
    "type": "linux",
    "refId": ObjectId("...")
}

$applicationIds也是同样情况。

问题出现在$configurationIds$applicationIds中没有记录时,我会得到以下内容:

{
    "type": "linux"
}

我不希望出现这种情况,如果没有$applicationIds,我希望对象为空。

另外,我在这个阶段之前对$applicationIds进行了$unwind操作(使用preserveNullAndEmptyArrays选项),因此每个文档中只能有一个或没有applicationIds。同样适用于configurationIds

英文:

I have the following project:

{
    '$project': {
        '_id': 1,
        'applicationIds': {
            'type': 'linux',
            'refId': '$applicationIds'
        },
        'configurationIds': {
            'type': 'linux',
            'refId': '$configurationIds'
        }
    }
}

As long as there is at least one record in $configurationIds I will get something like this:

{
    'type': 'linux',
    'refId': ObjectId('...')
}

And same with $applicationIds..

The issue arises when there are no records in $configurationIds or $applicationIds then I get this:

{
    'type': 'linux'
}

I don't want this, if there are no $applicationIds, I just want the object to be empty.

Btw I do an $unwind on $applicationIds (with preserveNullAndEmptyArrays) just before this stage so there can only be either one or no applicationIds in each document. Same goes for applicationIds.

答案1

得分: 2

你可以编写一个条件来检查字段是否缺失或存在。这篇帖子 展示了一种检查的方法,如果不存在则投影一个空对象:

db.collection.aggregate([
  {
    $project: {
      _id: 1,
      applicationIds: {
        $cond: {
          if: { $ne: [ { $type: "$applicationIds" }, "missing" ] },
          then: { type: "linux", refId: "$applicationIds" },
          else: {}
        }
      },
      configurationIds: {
        $cond: {
          if: { $ne: [ { $type: "$configurationIds" }, "missing" ] },
          then: { type: "linux", refId: "$configurationIds" },
          else: {}
        }
      }
    }
  }
])

播放场

如果你不想在投影后保留不存在的字段,而是使用 $$REMOVE这篇帖子 提供了一些示例用法:

db.collection.aggregate([
  {
    $project: {
      _id: 1,
      applicationIds: {
        $cond: {
          if: { $ne: [ { $type: "$applicationIds" }, "missing" ] },
          then: { type: "linux", refId: "$applicationIds" },
          else: "$$REMOVE"
        }
      },
      configurationIds: {
        $cond: {
          if: { $ne: [ { $type: "$configurationIds" }, "missing" ] },
          then: { type: "linux", refId: "$configurationIds" },
          else: "$$REMOVE"
        }
      }
    }
  }
])

播放场

英文:

you can write a condition to check if the field is missing or not. This post shows a way to check that and if doesn't exists project an empty object

db.collection.aggregate([
  {
    $project: {
      _id: 1,
      applicationIds: {
        $cond: {
          if: { $ne: [ { $type: "$applicationIds" }, "missing" ] },
          then: { type: "linux", refId: "$applicationIds" },
          else: {}
        }
      },
      configurationIds: {
        $cond: {
          if: { $ne: [ { $type: "$configurationIds" }, "missing" ] },
          then: { type: "linux", refId: "$configurationIds" },
          else: {}
        }
      }
    }
  }
])

playground

if you don't want the non existing field after projecting as well instead of the empty object you can use $$REMOVE. This post has some example usage of it

db.collection.aggregate([
  {
    $project: {
      _id: 1,
      applicationIds: {
        $cond: {
          if: { $ne: [ { $type: "$applicationIds" }, "missing" ] },
          then: { type: "linux", refId: "$applicationIds" },
          else: "$$REMOVE"
        }
      },
      configurationIds: {
        $cond: {
          if: { $ne: [ { $type: "$configurationIds" }, "missing" ] },
          then: { type: "linux", refId: "$configurationIds" },
          else: "$$REMOVE"
        }
      }
    }
  }
])

playground

答案2

得分: 0

Sure, here's the translated code part:

db.myCollection.aggregate([
   {
      $project: {
         fieldToProject: {
            $cond: {
               if: { $exists: "$specificField", true },
               then: "$specificField",
               else: null
            }
         }
      }
   }
])
英文:
db.myCollection.aggregate([
   {
      $project: {
         fieldToProject: {
            $cond: {
               if: { $exists: ["$specificField", true] },
               then: "$specificField",
               else: null
            }
         }
      }
   }
])

huangapple
  • 本文由 发表于 2023年4月19日 21:38:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76055221.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定