I want to copy items from admin to newAdmins if it does not exist in the newAdmins
Before:
[
{
_id: "60801199bf57265ed8b786bc",
admins: [
"Kenny"
"Abu"
"Raj"
],
newAdmins: [
"Kenny"
"Abu"
]
}
]
After:
[
{
_id: "60801199bf57265ed8b786bc",
admins: [
"Kenny"
"Abu"
"Raj"
],
newAdmins: [
"Kenny"
"Abu"
"Raj"
]
}
]
Searched online but could not find a simpler way to do it.
One option is:
db.collection.update({},
[
{
$set: {
newAdmins: {
$setUnion: [
"$newAdmins",
"$admins"
]
}
}
}
],
{multi: true})
See how it works on the playground example
Related
I have an array that is like [1,2,1,2,3,5,2]. And I want to remove only one element amongst the selected elements. I used $pull operator and it doesn't work as I required, it remove all elements I specified.
db.user.updateOne({_id: ...}, {$pull:{'array': 1}})
I tried it and give this result: [2,2,3,5,2].
is there any way to get the result: [2,1,2,3,5,2]
This feature does not exist (and won't), as you can see in this Jira. ticket they choose they won't do this.
Here is a hacky work around - the strategy will be to find the index of the first matching element and slice it out of the array, like so:
db.collection.update({},
[
{
"$set": {
"array": {
"$concatArrays": [
{
$cond: [
{
$gt: [
{
"$indexOfArray": [
"$array",
1
]
},
0
]
},
{
"$slice": [
"$array",
0,
{
"$indexOfArray": [
"$array",
1
]
}
]
},
[]
]
},
{
"$slice": [
"$array",
{
"$add": [
{
"$indexOfArray": [
"$array",
1
]
},
1
]
},
{
"$size": "$array"
}
]
}
]
}
}
}
])
Mongo Playground
Query
$reduce the array starting with {"n-ar": [], "found": false}
the first time you find it you ignore it, and you set found=true
else you just $concat to add the member to the new-ar
*it can be generalized, like remove the first 4 occurences, if integer is used as found
*its pipeline update requires MongoDB >= 4.2
Playmongo
update({},
[{"$set":
{"ar":
{"$getField":
{"field": "n-ar",
"input":
{"$reduce":
{"input": "$ar",
"initialValue": {"n-ar": [], "found": false},
"in":
{"$cond":
[{"$and":
[{"$eq": ["$$this", 1]}, {"$eq": ["$$value.found", false]}]},
{"n-ar": "$$value.n-ar", "found": true},
{"n-ar": {"$concatArrays": ["$$value.n-ar", ["$$this"]]},
"found": "$$value.found"}]}}}}}}}])
My input:
[
{
"nfStatusNotificationUri": "http://172.19.0.2:32672/callback/nnrf-nfm/v1/onNFStatusEventPost/4e0becf9-c3ec-4002-a32b-2e35b76469b2",
"subscrCond": {
"serviceName": "namf-evts"
},
"subscriptionId": "36bc52dfdbdd4044b97ef15684706205",
"validityTime": "2022-04-30T16:40:48.274Z",
"reqNotifEvents": [
"NF_DEREGISTERED",
"NF_PROFILE_CHANGED",
"NF_REGISTERED"
]
},
{
"nfStatusNotificationUri": "http://172.19.0.2:32672/callback/nnrf-nfm/v1/onNFStatusEventPost/5319def1-af0b-4b7b-a94e-b787e614c065",
"subscrCond": {
"serviceName": "nbsf-management"
},
"subscriptionId": "e2e904bb52ca4fd6b048841c83a4c38e",
"validityTime": "2022-04-30T16:40:48.26Z",
"reqNotifEvents": [
"NF_DEREGISTERED",
"NF_PROFILE_CHANGED",
"NF_REGISTERED"
]
},
{
"nfStatusNotificationUri": "http://172.19.0.2:32672/callback/nnrf-nfm/v1/onNFStatusEventPost/31dfe10b-4020-47bd-943e-a3e293086b29",
"subscrCond": {
"serviceName": "namf-comm"
},
"subscriptionId": "e508077fab4f4b8d9dd732176a3777b9",
"validityTime": "2022-04-30T16:40:48.273Z",
"reqNotifEvents": [
"NF_DEREGISTERED",
"NF_PROFILE_CHANGED",
"NF_REGISTERED"
]
}
]
I would like to sort it by "subscriptionId" and "serviceName".
I can sort by subscriptionId but I don't know how to specify serviceName to the following expression.
jq -S '.|=sort_by(.subscriptionId)|.[].reqNotifEvents|=sort |del(.[].subscriptionId, .[].validityTime, .[].nfStatusNotificationUri)'
You can parameterize sort_by by a list of keys like so:
sort_by(.subscriptionId, .subscrCond.serviceName)
Online demo
I have an object schema that looks like this:
{
"_id":"ObjectId(""30t00594537da2r7awe083va"")",
"balances":{
"intraday":[
[
1630939075734,
1899.09
],
[
1630939435939,
1899.32
],
[
1632306730756,
0
],
[
1632306759376,
0
],
[
1632272012916,
1372.22
]
]
}
}
I want to remove all arrays within "balances.intraday" array whose the second element is equal to 0.
so my desired array will looks like this:
{
"_id":"ObjectId(""30t00594537da2r7awe083va"")",
"balances":{
"intraday":[
[
1630939075734,
1899.09
],
[
1630939435939,
1899.32
],
[
1632272012916,
1372.22
]
]
}
}
I tried to use the $pull command but it only removes the index and not the whole array.
======================= Edit =======================
Thanks to Tom Slabbaert the solution is as follows :
db._get_collection().update_many(
{},
[
{
"$set": {
"balances.intraday": {
"$filter": {
"input": "$balances.intraday",
"cond": {
"$ne": [
{
"$arrayElemAt": [
"$$this",
1
]
},
0
]
}
}
}
}
}
])
You should use pipelined updates for this, like so:
db.collection.updateMany(
{},
[
{
$set: {
"balances.intraday": {
$filter: {
input: "$balances.intraday",
cond: {
$ne: [
{
$arrayElemAt: [
"$$this",
1
]
},
0
]
}
}
}
}
}
])
Mongo Playground
I'm trying to parse JSON which is like below:
"price": [
[
1539283140000,
6288.07
],
[
1539283440000,
6285.82
],
[
1539283740000,
6285.81
],
[
1539284041000,
6280.37
],
[
1539284340000,
6280.19
]
Please help me deal with this. And is there a possibility to decode the timestamp value to a date.
Correct json
{
"price": [
[
1539283140000,
6288.07
],
[
1539283440000,
6285.82
],
[
1539283740000,
6285.81
],
[
1539284041000,
6280.37
],
[
1539284340000,
6280.19
]
]
}
struct Root: Codable {
let price: [[Double]]
}
let res = try? JSONDecodable().decode(Root.self,from:jsonData)
Upon the aggregate function, the output i have got is of the form :-
> [ { DescriptionArray:
[ 'Des1',
'Des2',
'Des3',
'Des4' ],
PicArray:
[ 'Pic1.jpeg',
'Pic2.jpeg',
'Pic3.jpeg',
'Pic4.jpeg' ] } ]
But, i want the output to be of the form :-
>[ { DescriptionArray:
[
['Des1'],
['Des2'],
['Des3'],
['Des4' ]
],PicArray:
[
['Pic1.jpeg'],
['Pic2.jpeg'],
['Pic3.jpeg'],
['Pic4.jpeg']
] } ]
The aggregate function of mine is as follows:-
>User.aggregate([
{
"$project": {
"_id": 0,
"DescriptionArray": {
"$reduce": {
"input": "$services.description",
"initialValue": [],
"in": {
"$concatArrays": [
"$$this",
"$$value"
]
}
}
},
"PicArray": {
"$reduce": {
"input": "$services.badpic",
"initialValue": [],
"in": {
"$concatArrays": [
"$$this",
"$$value"
]
}
}
}
}
}
])
The schema of my database is as follows:-
> var serviceSchema = new mongoose.Schema({
description:[String],
pic:[String]
})
Is there any way, i can get the output of my desired format?