Given the following MongoDB document structure (which I cannot change), I'm not sure how to read this in JavaScript?
so
loginHistory
is the main field name. It contains anObject
type (okay???)it can then contain multiple children fields (this above example has only ONE child), which are arrays. These field names are dynamic, but unique.
the 'array' content is a C#
DateTimeOffset
, I've been told.
So in the example above, Jane
is the field and the value is an Array
, but really it's a DateTime.Offset
.
Here's another document I've found:
- 4x fields
So i don't know how to read this with node/JavaScript. Oh - and the field loginHistory
might not exist on some documents, also :(
So given that existing document schema/structure, I need to somehow read in each loginHistory value and then create a new document (which i'll do other stuff with later).
This is some JavaScript code I tried, but doesn't work:
users.loginHistory.forEach(loginHistory => {
// do stuff, like create a new { id = users._id, name = "Jane", createdOn = "that date/time offset" }
}
CodePudding user response:
Assuming we have an input set of docs like the screen shots e.g.:
var r = [
{
loginHistory: {
"Jane": [ 1648835363929, 0 ],
"Bob": [ 1648835363929, 0 ]
}
},
{
noLoginHistory: "nope"
},
{
loginHistory: {
"Dan": [ 1648835363929, 0 ],
"Dave": [ 1648835363929, 0 ],
"Jane": [ 1648835363929, 0 ]
}
}
];
then the following pipeline will create new, "converted" docs in a collection named foo2
.
db.foo.aggregate([
// OK if loginHistory does not exist. X will be set to null
// and the $unwind will not produce anything:
{$project: {X: {$objectToArray: "$$ROOT.loginHistory"} }},
{$unwind: "$X"},
// Now we have individual docs of
// X: {k: name, v: the array}
// The OP wanted to make a new doc for each one. I don't know
// what function to apply to turn X.v[0] into a MongoDB datetime
// because I don't know what that big int (637807576034080256) is
// supposed to be so I used regular ms since epoch for the example
// instead. The OP will have to get more creative with division
// and such to turn 637807576034080256 into something "toDate-able"
// in MongoDB. You *could* store the big int as is but it is always
// good to try to turn a datetime into a real datetime in mongodb.
{$project: {
_id: false,
name: '$X.k',
createdOn: {$toDate: {$arrayElemAt:['$X.v',0]}}
}}
// Now we have docs like :
// {name: "Jane", createdOn: ISODate(...) }
// By calling $out to a new collection, a new _id will be assigned
// to each:
,{$out: "foo2"}
]);