Get array of key/value pairs from document in mongodb - mongodb

I'm trying to return all the key/value pairs from a document as an array.
Sample Doc :
{key:"value", key2:"value2", key3:"value3"}
Required Output :
[{key:"value"},{key2:"value2"},{ key3:"value3"}]
Ive tried using the $objectToArray operator but it doesn't work for single documents.

You can try below query :
db.collection.aggregate([
{
$project: {
_id: 0,
data: {
$map: {
input: { $objectToArray: "$$ROOT" },/** Convert object to array & iterate on each object */
in: {
/** Consider each object (k:...,v:...) as an array &
convert back to actual object (k:v) & push to 'data' array field */
$arrayToObject: [
[
"$$this"
]
]
}
}
}
}
}
])
Test : MongoDB-Playground

Related

MongoDB extract value from array of objects into simple array

I have a collection of documents that I initially set up like this:
{
_id: "some_id",
data: [
{
_id: "_id_foo",
value: "foo"
},
{
_id: "_id_bar",
value: "bar"
}
]
}
Now, I realized I don't need the value field, so I can turn the array of objects into an array of strings ["_id_foo", "_id_bar"]. I'm trying to build a pipeline to accomplish this, but I'm failing miserably.
If it's easier, I can also create a data_new array and delete the old one later.
Thanks!
You can use the map operator and convert the array of objects to array of strings.
db.collection.aggregate([
{
$addFields: {
data: {
$map: {
input: "$data",
as: "data",
in: "$$data._id"
}
}
}
}
])
Playground

how to modify every field of a nested document mongo?

so imagine I have the following document:
{
"_id":...,
"data":{"a":[],"b":[],"x":[]}
}
I don't know beforehand which fields the subdocument data may have. I just know that every field in that subdocument will be an array
How do I make an update so that the object results like:
{
"_id":...,
"data":{"a":[1],"b":[1],"x":[1]}
}
Constraint: Using only mongodb operators. One single update. Without knowing the fields inside the 'data' subdocument
db.collection.update({},
[
{
$set: {
data: {
$arrayToObject: {
$map: {
input: { $objectToArray: "$data" },
as: "d",
in: { k: "$$d.k", v: [ 1 ] }
}
}
}
}
}
])
mongoplayground

How do I Convert a subset of fields in all documents to $toDouble?

I have a database with many documents structured like so:
Date:2021-01-02T08:00:00.000+00:00
FIT_ME44_Volume:"984385"
LT_MJ01:"0"
LT_MJ08:"0"
LT_MJ16:"-34.526024"
FIT_ME56_Volume:"0"
FIT_MJ22_Volume:"9538598"
LT_MJ26:"-61.803848"
FIT_ME52_Volume:"2734271"
LT_ME16:"0"
FIT_MJ28_Volume:"0"
LT_ME29:"2.10552"
LT_ME02:"2.005206"
LT_ME50:"8.732683"
FIT_MJ13_Volume:"0"
FIT_ME02_Volume:"1131376"
FIT_ME23_Volume:"2585415"
LT_ME03:"6.918576"
FIT_MJ08_Volume:"0"
FIT_MJ18_Volume:"0"
QQCr_Total_Plant:"5471052"
FIT_ME03_Volume:"103164"
FIT_ME51_Volume:"3587575"
LT_ME06:"24.423439"
FIT_ME46_Volume:"1619"
What I would like to do is convert all fields in all documents except Date from string to double. I can do this on a field by field basis, but how do I accomplish this in bulk?
You can try an update with aggregation pipeline query starting from MongoDB 4.2,
$objectToArray convert root document from object to key-value array of object format
$map to iterate loop of above converted array
return k key as it is
$cond to check is key in the provided array then don't convert means ignore and return existing value, you can also add fields name if don't want to convert
else $toDouble to convert a string value to double
$arrayToObject back to convert above key-value array of objects to an real object format
$replaceRoot to replace above converted object to root
db.collection.updateMany(
{},
[{
$replaceRoot: {
newRoot: {
$arrayToObject: {
$map: {
input: { $objectToArray: "$$ROOT" },
in: {
k: "$$this.k",
v: {
$cond: [
{ $in: ["$$this.k", ["Date", "_id"]] },
"$$this.v",
{ $toDouble: "$$this.v" }
]
}
}
}
}
}
}
}]
)
Playground

update array of objects with an array in a mongodb aggregation

I have the following situation in my aggregation: At some point my documents are holding an array of objects and an array of the same length at the root level. An example would be:
{_id:0,
cars:[{name:"vw polo",door:3},{name:"vw golf",door:5}],
possible_colors:[["black","blue"],["white"]]}
What I'm trying now is to update project the possible colors into each object of the cars array. The expected result should look as follows.
{_id:0,
cars:[{name:"vw polo",door:3,possible_colors:["black","blue"]},
{name:"vw golf",door:5,possible_colors:["white"]}],
}
I already tried {$addfields:{cars:{$zip:[$cars,$possible_colors]}}}, but this creates a list of arrays, where each array contains the object and the correct subarray, but i was not able to merge them.
The $zip operator is a good approach however you need additional $map along with $mergeObjects in order to get the desired structure:
db.collection.aggregate([
{
$addFields: {
cars: {
$map: {
input: { $zip: { inputs: [ "$cars", "$possible_colors" ] } },
in: {
$mergeObjects: [
{ $arrayElemAt: [ "$$this", 0 ] },
{ possible_colors: { $arrayElemAt: [ "$$this", 1 ] } }
]
}
}
}
}
}
])
Mongo Playground

Return keys of an array field from MongoDB

Below is the mongodb collection sample data. I'm trying to fire a query which will return and array of a property in my collection.
Sample Docs :
{
"_id" : ObjectId("5e940d6c2f804ab99b24a633"),
"accountId" : ObjectId("7e1c1180d59de1704ce43557"),
"description":"some desc",
"configs": {},
"dependencies" : [
{
"commute" : {},
"distance" : {},
"support":{}
}
]
}
Expected output :
{
[0]:commute
[1]:distance
[2]:support
}
I've tried to get the response and iterate the dependencies object also I tried using es6 to convert it to an array object. But it is an expensive operation as this list would be really large. If at all there exists and such approach in Mongo to convert the response into array
You can try below aggregation query :
db.collection.aggregate([
{
$project: {
_id: 0,
dependenciesKeys: {
$reduce: {
input: "$dependencies", // Iterate over 'dependencies' array
initialValue: [],
in: {
$concatArrays: [ /** concat each array returned by map with holding 'value */'
"$$value",
{
$map: {
input: {
$objectToArray: "$$this" /** Convert each object in 'dependencies' to array [{k:...,v:...},{k:...,v:...}] & iterate on each object */
},
in: "$$this.k" // Just return keys from each object
}
}
]
}
}
}
}
}
])
Test : MongoDB-Playground
Ref : $reduce , $map , $concatArrays , $objectToArray & $project
I think you should try Object to array, which is an aggregation pipeline operator.
Also the Aggregation Pipeline is pretty useful concept, it makes you create a pipeline of operations that process your data sequentially. You can imagine it as following; you create a steps 'Pipeline' every step make a certain operation 'Aggregate operation' in your data, which results to some certain data shape,like an array as you want.