i have a mongoose document that contains two ages. The minimum age to go to the attraction and the maximum one.
I need to query my database to get all attractions between 0 and 2 years old.
But this won't work :
"ageMin": {
"$lte": 2
},
"ageMax": {
"$gte": 0
},
Because most of my attraction are between 0 and 99.
To help you visualise i made an example:
attractionOne: {
name: "Deadly Looping",
ageMin: 12,
ageMax: 99
}
attractionTwo: {
name: "Easy Ladybug",
ageMin: 0,
ageMax: 12
}
Thank you.
If you need to match if those ranges are overlapping with 0-2 range then you're close, just need to check if 0-2 range is between min and max age. Try:
db.attractions.find({ ageMin: { $lte: 0 }, ageMax: { $gte: 2 } })
Related
I have data collection which has different students with diff marks,I want to count how many students got certain numbers of 100,90,80,70,60 etc marks and if no student has that specific mark, I want that resulting output as 0
Eg:
,
{ $group: { "_id": studentMarks, "studentMarksTotal": { $sum: 1 } } },
{ $sort: { _id: 1 } },
{
$project: {
_id: 0,
studentMarksTotal: 1,
studentMarks:{
$cond: { if: { $eq: ["$_id", "$studentMarks"] }, then: "$_id", else: "0" },
,
},
}}
]
this gives the result for values that have count
Eg: studentMarks:70,
studentMarksTotal:9
studentMarks:90,
studentMarksTotal:6
but I also want count data if no student got certain marks
eg:studentMarks:70,
studentMarksTotal:9
studentMarks:90,
studentMarksTotal:6
studentMarks:100,
studentMarksTotal:0
How can I achieve not, I have tried $ifNull and if else also but am unable to get the desired result
If anyone could help me with this, Thanks in advance.
Currently I am making scheduling system and storing information in mongodb
partial of my model looks like this
{
timings: [{from: "00:00", to: "01:00"}],
weekend: [0, 5, 6]
}
I am not sure if this will be good in the long run
can you please help me decide how to better store time in my documents
MongoDB does not have any time/interval data type, so you have to build your own solution. Some general notes:
Use week days according to ISO-8601 standard, i.e. first day (1) of week is Monday. Then it will be easier to create a Date value with $dateFromParts. For hour values use always 24-hour format.
You may consider to store times as
{from: {hour: 0, minute: 0}, to: {hour: 13, minute: 0}}
Otherwise, when you have to create Date value (e.g. for comparison), then it would be:
{
$dateFromParts : {
...,
hour: { $toInt: { $arrayElemAt: [ { $split: [ "$from", ":" ] }, 0 ] } },
minute: { $toInt: { $arrayElemAt: [ { $split: [ "$from", ":" ] }, 1 ] } }
}
}
Compared to
{
$dateFromParts : {
...,
hour: "$from.hour",
minute: "$from.minute"
}
}
Another approach is to store real Date, e.g. 0000-01-01T13:00:00 or any other arbitrary day value. When you use such values, simply ignore the date part.
Or you store number of minutes (0..1'440) or seconds (0..86'400) from midnight. However, such numbers are not user-friendly to read.
I am using GRPCv3 on node.js
I have a .proto file with the following message:
message ProductAvailabilityWithRatesResponse {
// How many slots are available for this day/time. Mandatory.
int32 capacity = 1;
// Date for when this product is available. Mandatory.
Date date = 2;
// When does this event start? Unset if this product does not support times.
Time time = 3;
// When does a pickup for this product start? Unset if this product does not support times or pickups.
Time pickupTime = 4;
// Rates with prices. Mandatory (should at least have one entry).
repeated RateWithPrice rates = 5;
}
on the server using console.log i see this output:
{ capacity: 1,
date: { year: 2019, month: 7, day: 1 },
rates: [ { rateId: 1, pricePerPerson: [Object] } ],
time: { hour: 9, minute: 0 } }
and on a client using node.js too:
{ rates:
[ { rateId: '1',
pricePerPerson: [Object],
pricingOptions: 'pricePerPerson' } ],
capacity: 0,
date: { year: 2019, month: 7, day: 1 },
time: { hour: 9, minute: 0 },
pickupTime: null }
but another person using a java client tells me that he sees:
2019-06-26 10:59:39,442 ← getProductAvailability::grpc response {date { year: 2019 month: 7 day: 1 } time { hour: 9 } rates { rateId: "1" pricePerPerson { pricingCategoryWithPrice { pricingCategoryId: "30" price { currency: "EUR" amount: "145" } } pricingCategoryWithPrice { pricingCategoryId: "31" price { currency: "EUR" amount: "150" } } } }}
where capacity is not set.
If it's value is 1 and not 0, everything works well everywhere.
Is it possible?
How can i force the server to output the value?
I already tried using capacity = parseInt(capacity)
I have a collection named users
var UserSchema = new Schema({
name: String,
age: Number,
points: {type: Number, default: 0}
})
all users have some different points like 5, 10, 20, 50
so i want to count the number of users having 5 points, 10 points etc, and want to show the counted users details also, like who are those users which are having 5 points, 10 points etc.
how to write query for that in $aggregate
You can write a group stage and push all the values you need using the $push operator
db.collection.aggregate([
{
"$group": {
"_id": "$points",
"details": {
"$push": {
"name": "$name",
"age": "$age"
}
}
}
}
])
In the above example, I've grouped according to points and for each group, you'll get an array containing the name and age of the people having those points
I have a program that runs every 5 minutes and checks the last time a users data was updated. If it's been greater than 4 hours an update routine is called but as the service grows, I've seen some spikes in the number of calls at given times. I want to start spreading out the update times. Since I know each time the program updated each users data last, I was wondering if there was an elegant way to find the largest gap between times and set the new users update time to that?
Here's an example. Given the following data:
{
"_id": "1",
"updatedAt": "2018-01-17T01:12:33.807Z"
},{
"_id": "2",
"updatedAt": "2018-01-17T03:17:33.807Z"
},{
"_id": "3",
"updatedAt": "2018-01-17T02:22:33.807Z"
},{
"_id": "4",
"updatedAt": "2018-01-17T02:37:33.807Z"
}
The largest time between the given updates is 1 hour and 10 minutes between id: 1 and id: 3. I want a function that can find that largest gap of time and returns the a suggested update time for the next item added to the database of '2018-01-17T01:47:33.807Z'. Which was calculated by taking the 1 hour and 10 minutes and dividing it by 2 and then adding it to id: 1's date.
I would also like to spread out all the existing users update time but I suppose that would be a different function.
You can't use aggregation framework for a difference style comparison. However you can use map reduce to get the largest time diff between documents.
Something like
db.col.mapReduce(
function () {
if (typeof this.updatedAt != "undefined") {
var date = new Date(this.updatedAt);
emit(null, date);
}
},
function(key, dates) {
result = {"prev":dates[0].getTime(), "last":dates[0].getTime(), "diff":0}
for (var ix = 1; ix < dates.length; ix++) {
value = dates[ix].getTime();
curdiff = value - result.prev;
olddiff = result.diff;
if(olddiff < curdiff)
result = {"prev":value, "diff":curdiff, "last":result.prev};
}
return result;
},
{
"sort":{"updatedAt":1},
"out": { "inline": 1 },
"finalize":function(key, result) {
return new Date(result.last + result.diff/2);
}
}
)
Aggregation query:
db.col.aggregate([
{"$match":{"updatedAt":{"$exists":true}}},
{"$sort":{"updatedAt":1}},
{"$group":{
"_id":null,
"dates":{"$push":"$updatedAt"}
}},
{"$project":{
"_id":0,
"next":{
"$let":{
"vars":{
"result":{
"$reduce":{
"input":{"$slice":["$dates",1,{"$subtract":[{"$size":"$dates"},1]}]},
"initialValue":{"prev":{"$arrayElemAt":["$dates",0]},"last":{"$arrayElemAt":["$dates",0]},"diff":0},
"in":{
"$cond":[
{"$lt":["$$value.diff",{"$subtract":["$$this","$$value.prev"]}]},
{"prev":"$$this","last":"$$value.prev","diff":{"$subtract":["$$this","$$value.prev"]}},
"$$value"
]
}
}
}
},
"in":{
"$add":["$$result.last",{"$divide":["$$result.diff",2]}]
}
}
}
}}
])