How to use unixtime with $dateToString mongodb - node.js

is't possible to use unixtime with $dateToString.
this is the schema:
var wifiSchema = mongoose.Schema({
ID: String,
Vendor: String,
SSID: String,
TimeStamp: {
date: Number,
},
AP: String,
MAC: String,
ID_frame: String,
RSSI: Number,
Type: String
}, { collection: 'wifiScan' });
var wifi = mongoose.model('wifi', wifiSchema);
and this is the mongoose function:
wifi.aggregate([
{$group:{_id:{"time" : "$TimeStamp.date"},uniqueCount: {$addToSet: "$MAC"}}},
{$project:{"time":1,uniqueCustomerCount:{$size:"$uniqueCount"}, yearMonthDayUTC: { $dateToString: { format: "%Y/%m/%d", date: new Date('$$TimeStamp.date') } } } },
{$sort:{'uniqueCustomerCount': -1 }}
]).limit(20).exec().then(notes => {
res.status(200).json({data:notes});
console.log(notes);
});
The problem that I get an error on converting the date variable from unix fo date format using $dateToString, this is the result I get:
{ _id: { time: 1529235720000 },
uniqueCustomerCount: 26,
yearMonthDayUTC: '1970/01/01' } ]
I don't know why I get is as '1970/01/01'. thanks for the help.
Second try:
I have tried this $project example also:
{$project:{"time":1,uniqueCustomerCount:{$size:"$uniqueCount"},"Time": { "$add": [ new Date(0), "$TimeStamp.date" ]} } },

Related

ts mongoose query specific string attribute as string array (not object array)

I have this mongoose schema, and I want to query all IP attributes as a string array.
like [IP,IP,IP,IP] this, not [ { ip : ip} ]
const proxyIpSchema = new Schema<IProxyIp>({
ip: {
type: String,
required: true,
//ignore duplicate ip
unique: true,
},
port: {
type: Number,
required: false,
default: null
},
reason: {
type: String,
required: true,
default: 'Unknown Detection.'
}
},
{
timestamps: true,
}
);
I cant use a map function because it will eat the backend processing power. like this
I want all ips as a string array
//get all ips from mongo db and push to redis
await ProxyIp.find({}, { ip: 1 }).then(async (docs) => {
docs.map(async (doc) => {
await this.RedisClient?.sAdd(redisTable, doc.ip);
});
}).catch((err) => {
});
Here's one way you can put all the "ip"s into a single array (within an object).
db.ProxyIp.aggregate([
{
"$group": {
"_id": null,
"ips": {
"$push": "$ip"
}
}
},
{
"$unset": "_id"
}
])
Example output:
[
{
"ips": [
"102.118.108.76",
"34.234.240.83",
"123.76.73.33",
"134.81.197.85",
"193.122.45.195",
"54.25.18.14",
"185.68.124.193",
"3.105.130.68",
"52.72.204.78",
"117.212.118.167",
"199.155.140.226",
"64.194.68.59",
"57.4.147.57",
"190.116.4.243",
"179.111.74.98",
...
]
}
[
Try it on mongoplayground.net.

Find value from sub array within last 30 days using Mongoose

I am trying to locate a certain value in a sub array using Mongoose.js with MongoDB. Below is my Mongoose schema.
const foobarSchema = new mongoose.Schema({
foo: {
type: Array,
required: true
},
comments: {
type: Array,
required: false
},
createdAt: { type: Date, required: true, default: Date.now }
});
The value I am trying to get is inside foo, so in foo I always have one array at place [0] which contains an object that is like the below
{
_id
code
reason
createdAt
}
I'd like to get the value for reason for all records created in the last 30 days. I've looked around on stack overflow and haven't found anything I could piece together. Below is my existing but non working code
const older_than = moment().subtract(30, 'days').toDate();
Foobar.find({ ...idk.. req.body.reason, createdAt: { $lte: older_than }})
edit add mock document
{
foo: [{
_id: 'abc123',
code: '7a',
reason: 'failure',
createdAt: mongo time code date now
}],
comments: []
}
curent code half working
const reason = req.params.reason
const sevenAgo = moment().subtract(7, 'days').toISOString()
Foo.aggregate([
{
$match: {
"foo.createdAt": {
$gte: sevenAgo
},
"foo.reason": {
reason
}
}
},
{
$project: {
reason: {
$arrayElemAt: [
"$foo.reason",
0
]
}
}
}
])
Currently returns blank array - no query failure - which is wrong it should return at least 1 document/record as that is what is in the DB that matches
expected mock data
[
{
code: 7a,
reason: failure
}
{
code: 7a,
reason:failure
}
]

Mongodb update multiple documents with different values

I have been trying to use updatemany with mongoose. I want to update the values in database using an array of objects.
[
{
"variantId": "5e1760fbdfaf28038242d676",
"quantity": 5
},
{
"variantId": "5e17e67b73a34d53160c7252",
"quantity": 13
}
]
I want to use variantId as filter.
Model schema is:
let variantSchema = new mongoose.Schema({
variantName: String,
stocks: {
type: Number,
min: 0
},
regularPrice: {
type: Number,
required: true
},
salePrice: {
type: Number,
required: true
}
})
I want to filter the models using variantId and then decrease the stocks.
As you need to update multiple documents with multiple criteria then .updateMany() wouldn't work - it will work only if you need to update multiple documents with same value, Try this below query which will help you to get it done in one DB call :
const Mongoose = require("mongoose");
let variantSchema = new mongoose.Schema({
variantName: String,
stocks: {
type: Number,
min: 0
},
regularPrice: {
type: Number,
required: true
},
salePrice: {
type: Number,
required: true
}
})
const Variant = mongoose.model('variant', variantSchema, 'variant');
let input = [
{
"variantId": "5e1760fbdfaf28038242d676",
"quantity": 5
},
{
"variantId": "5e17e67b73a34d53160c7252",
"quantity": 13
}
]
let bulkArr = [];
for (const i of input) {
bulkArr.push({
updateOne: {
"filter": { "_id": Mongoose.Types.ObjectId(i.variantId) },
"update": { $inc: { "stocks": - i.quantity } }
}
})
}
Variant.bulkWrite(bulkArr)
Ref : MongoDB-bulkWrite
I don't think this can be done with a single Model.updateMany query. You will need to loop the array and use Model.update instead.
for (const { variantId, quantity } of objects) {
Model.update({ _id: variantId }, { $inc: { stocks: -quantity } });
}
To run this in a transaction (https://mongoosejs.com/docs/transactions.html), the code should look something like this (however I have not tried or tested this):
mongoose.startSession().then(async session => {
session.startTransaction();
for (const { variantId, quantity } of objects) {
await Model.update({ _id: variantId }, { $inc: { stocks: -quantity } }, { session });
}
await session.commitTransaction();
});

Mongoose giving weird result when pulling an element from an array inside an object in mongoose schema [duplicate]

This question already has answers here:
Mongoose deleting (pull) a document within an array, does not work with ObjectID
(8 answers)
Closed 3 years ago.
I have a mongoose schema that looks like :-
{
"_id" : ObjectId("some_id"),
"repDet" : {
"devIDs" : [
"dev1_B37",
"dev2_B38",
"dev3_B26"
],
"sensors" : [
"D30"
],
"triggers" : [
"initial"
]
}
I want to pull "dev2_B38" from the array "devIDs" inside the object "repDet".
The following command works in mongo db :-
schedules.updateOne({ added_by: currentUser, "repDet.devIDs": "dev2_B38" },{$pull : {"repDet.devIDs": "dev2_B38"}})
perfectly.
But the same command doesnt work in mongoose. The mongoose version that I have tried on is
5.0.18 & 5.7.11.
what it does it removes all the other devIDs from the array and keeps just the "dev_B38" and also converting "devIDs" into a string from an array. The output looks like :-
{
"_id" : ObjectId("some_id"),
"repDet" : {
"devIDs" : "dev2_B38",
"sensors" : [
"D30"
],
"triggers" : [
"initial"
]
}
I have tried updateOne, update, findOneAndUpdate all of these.
I also tried modifying it like :-
schedules.updateOne({ added_by: currentUser, "repDet.devIDs": "dev2_B38" },{$pull : {"repDet" {"devIDs": "dev2_B38"}}})
but still it gave me the same result.
The exact schema is :-
var scheduleSchema = new mongoose.Schema({
title: { type: String },
message: { type: String },
devID: { type: String },
sensors: [{
sensorId: String,
sensorName: String,
unit: String
}],
selectedContacts: [{
_id: { type: mongoose.Schema.Types.ObjectId, ref: 'Contact' },
name: String,
mobiles: [Number],
emails: [String]
}],
repDet: { type: Object },
invocationTime: { type: String },
invocationDays: Array,
startTime: { type: String },
endTime: { type: String },
interval: { type: Number },
repeat: { type: Number },
url: String
});
Kindly help me with this.
Thank you
schedules.updateOne({ _id: currentUser},
{$pull : {"repDet.devIDs":"dev1_B37"}})
try this

Add or push new object to nested mongodb document

I can't seem to find an answer to this on Stack or in the Mongoose docs. How do I added a new object into a nested document?
This is my current schema:
var SessionsSchema = mongoose.Schema({
session: {
sid: String,
dataloop: {
timeStamp: Date,
sensorValues:{
value: Number,
index: Number
}
}
}
});
Upon receiving new data from the client, I need to push into the existing session document, i've tried both $addToSet and $push but neither are giving me the correct results.
This is the $push:
Sessions.findOneAndUpdate(
{ 'session.sid': sessionID },
{
'$push:': {dataloop:{
timeStamp: datemilli,
sensorValues:{
value: pressure,
index: indexNum,
sessionTime: relativeTime
}
}
}
},
function(err,loop) {
console.log(loop);
}
)
Here is my expected output:
_id:58bb37a7e2950617355fab0d
session:Object
sid:8
dataloop:Object
timeStamp:2017-03-04 16:54:27.057
sensorValues:Object
value:134
index:18
sessionTime:0
dataloop:Object // <----------NEW OBJECT ADDED HERE
timeStamp:2017-03-04 16:54:27.059
sensorValues:Object
value:134
index:18
sessionTime:0
dataloop:Object // <----------ANOTHER NEW OBJECT
timeStamp:2017-03-04 16:54:27.059
sensorValues:Object
value:134
index:18
sessionTime:0
__v:0
If you consider to change your Schema to include a dataloop array :
var SessionsSchema = mongoose.Schema({
session: {
sid: String,
dataloop: [{
timeStamp: Date,
sensorValues: {
value: Number,
index: Number
}
}]
}
});
You could use $push on session.dataloop to add a new dataloop item :
Sessions.findOneAndUpdate({ 'session.sid': sessionID }, {
'$push': {
'session.dataloop': {
timeStamp: datemilli,
sensorValues: {
value: pressure,
index: indexNum,
sessionTime: relativeTime
}
}
}
},
function(err, loop) {
console.log(loop);
}
)

Resources