I have a set of documents in a mongo collection that have a schema like so:
{
"itemIds":{
"12341234-1234-1234-1234-123412341234": true,
"23452345-2345-2354-2345-234523452354": false,
"34563456-3456-3456-3456-345634563456": true
}
}
Because of our move to azure cognitive search, I need to use a mongo projection to get the data to look like this:
{
"itemIds": ["12341234-1234-1234-1234-123412341234",
"34563456-3456-3456-3456-345634563456"]
}
The properties with a false value should be excluded, and the properties with a true value should be converted to array values.
CodePudding user response:
Option 1. Maybe something like this:
db.collection.aggregate([
{
"$addFields": {
"itemIds": {
"$filter": {
"input": {
"$objectToArray": "$itemIds"
},
"as": "item",
"cond": {
$eq: [
"$$item.v",
true
]
}
}
}
}
},
{
$project: {
_id: "$_id",
itemIds: "$itemIds.k"
}
}
])
Explained:
- In the addFileds stage convert the object to array to get the key /values in the form k,v so you can filter only the true values.
- In the project stage project the _id and itemIds.k values inside the itemIds array
Option 2. Faster option via single stage: addFields/$map/$filter:
db.collection.aggregate([
{
"$addFields": {
"itemIds": {
"$map": {
"input": {
"$filter": {
"input": {
"$objectToArray": "$itemIds"
},
"as": "item",
"cond": {
$eq: [
"$$item.v",
true
]
}
}
},
"as": "it",
"in": "$$it.k"
}
}
}
}
])
Explained:
Map the filtered values from ObjectToArray to project in addFields only the necessary array values.