mongodb - 如果在数组中找不到匹配项,则返回第一个元素
问题描述
我有以下文件:
{
_id: 123,
state: "AZ",
products: [
{
product_id: 1,
desc: "P1"
},
{
product_id: 2,
desc: "P2"
}
]
}
我需要编写一个查询以从 products 数组中返回一个元素,其中 state 为“AZ”且 product_id 为 2。如果找不到匹配的 product_id,则返回 products 数组中的第一个(或任何)元素。
例如:如果 product_id 为 2(找到匹配项),则结果应为:
products: [
{
product_id: 2,
desc: "P2"
}
]
如果 product_id 为 3(未找到),则结果应为:
products: [
{
product_id: 1,
desc: "P1"
}
]
找到匹配项时,我能够满足一个条件,但不确定如何满足同一查询中的第二个条件:
db.getCollection('test').find({"state": "AZ"}, {_id: 0, state: 0, products: { "$elemMatch": {"product_id": "2"}}})
我也尝试使用聚合管道,但找不到有效的解决方案。
注意:这与以下问题不同,因为如果找不到匹配项,我需要返回默认元素: Retrieve only the queried element in an object array in MongoDB collection
解决方案
您可以尝试以下聚合
基本上你需要数组并检查它是否不包含任何元素或等于然后你必须$filter
使用数组的第一个元素。products
$cond
[]
$slice
products
db.collection.aggregate([
{ "$addFields": {
"products": {
"$cond": [
{
"$eq": [
{ "$filter": {
"input": "$products",
"cond": { "$eq": ["$$this.product_id", 2] }
}},
[]
]
},
{ "$slice": ["$products", 1] },
{ "$filter": {
"input": "$products",
"cond": { "$eq": ["$$this.product_id", 2] }
}}
]
}
}}
])
甚至使用$let
聚合
db.collection.aggregate([
{ "$addFields": {
"products": {
"$let": {
"vars": {
"filt": {
"$filter": {
"input": "$products",
"cond": { "$eq": ["$$this.product_id", 2] }
}
}
},
"in": {
"$cond": [
{ "$eq": ["$$filt", []] },
{ "$slice": ["$products", 1] },
"$$filt"
]
}
}
}
}}
])
推荐阅读
- php - 为什么 PHP 函数在实时服务器上不起作用?
- ios - 将图像添加到 UIActivityController
- webdriver - 如何在geckodriver中单击并按住一个元素一段时间?
- android - Android Api 30 级 Mediastore 艺术家,专辑名称更改
- python - 在 n 叉树的子节点数组中搜索一个节点
- html - JQuery 自动完成 - 重置隐藏的输入字段
- node.js - 如何使用 debian 8 在 docker 容器内使用 node-fetch 修复 CERT_HAS_EXPIRED 错误,与 Lets Encrypt DST_Root_CA_X3 证书相关
- assembly - 在 16 位裸机 nasm 组件中休眠 x 毫秒
- docker - 多代理 Confluent Kafka docker-compose.yml 文件
- docusignapi - 我想使用 Power Apps 创建一个 DocuSign 自定义连接器,但在我测试它时它不发送信封