I have a collection of Promo codes like this:-
{
'promoCode': 'XMAS22',
'country': 'USA',
'isExpirable': true,
'availability' : [
{
'startTimestamp' : startTimeVal1,
'endTimestamp': endTimeVal1,
'timezone': 'America/New_York'
},
{
'startTimestamp' : startTimeVal2,
'endTimestamp': endTimeVal2',
'timezone': 'America/Chicago'
},
{
'startTimestamp' : startTimeVal3,
'endTimestamp': endTimeVal3,
'timezone': 'America/Los_Angeles'
},
]
},
{
'promoCode': 'HAPPYDAY',
'country': 'USA',
'isExpirable': false,
'availability' : null
}
Promo Code XMAS22 is expirable in nature. So it has isExpirable status as true and has anvailability array, containing availability based on three timezones.
Promo code HAPPYDAY has isExpirable status false, so availability is null.
A user sends a timestamp value and a timezone. Something like 1628290101 and 'America/New_York'. The query should retrieve:-
{
'promoCode': 'XMAS22',
'country': 'USA'
},
{
'promoCode': 'HAPPYDAY',
'country': 'USA'
}
Promo code XMAS22 should be retrieved if:-
isExpirable = true and,
timezone value is gte startTimestamp and lte endTimestamp and,
timezone = America/New_York
Promo code HAPPYDAY should be retrieved because:-
isExpirable = false
How can I build up the query?
Query
here we assume the user endered timestamp=5 and timezone="America/New_York"
its the conditions you said, to pass if isExpirable=false or same timezone and timestamp between the start and end time.
finally project to keep only those 2 fields you want, you can remove the _id : 0 also if you want
*this is the find way with only query operators to use the index if you have one on startTimestamp and endTimestamp, we could do the same with aggregation in more programatic way with $filter but index wouldn't be used even if you had it.
Playmongo
find({"$or":
[{"isExpirable": {"$eq": false}},
{"$and":
[{"availability":
{"$elemMatch":
{"$and":
[{"startTimestamp": {"$lte": 5}}, {"endTimestamp": {"$gte": 5}},
{"timezone": {"$eq": "America/New_York"}}]}}}]}]},
{"projection": {"promoCode": 1, "country": 1}})
I'm building a fake API with json-server and I came across a problem when passing a query. I can show the parameters of a relationship when I use _expand, but when it is a relationship within a child it does not work.
For example, I have this json that I access by passinghttp://localhost:3000/schedules:
{
id: 1,
date: "2020-04-25T14:20:00-03:00",
status: "Novo serviço",
usersId: 5,
providersId: 1,
servicesId: 1,
},
Now to show the relationship with the user I pass the following query:
http://localhost:3000/schedules?_expand=users
It returns as follows:
{
id: 1,
date: "2020-04-25T14:20:00-03:00",
status: "Novo serviço",
usersId: 5,
providersId: 1,
servicesId: 1,
users: {
id: 5,
name: "Carla Pedroso",
photo: "https://cdn.pixabay.com/photo/2016/01/19/17/48/woman-1149911_960_720.jpg",
rating: 5,
addressesId: 1,
},
},
Well, my question is how I can show the JSON of the addressesId, because I already tried using_expand but without success.
change the schedule property "usersId" to "userId",
should work with
http://localhost:3000/schedules?_expand=user
and the response should be something like that:
{
id: 1,
date: "2020-04-25T14:20:00-03:00",
status: "Novo serviço",
providersId: 1,
servicesId: 1,
userId: 5,
user: {
id: 5,
name: "Carla Pedroso",
photo: "https://cdn.pixabay.com/photo/2016/01/19/17/48/woman-1149911_960_720.jpg",
rating: 5,
addressesId: 1
}
}
With json-server you can add the parent and children of an element to the result, but it will only bring one level, so it will not bring grandparents or grandchildren's.
In your case instead of looking at the schedules you can look at the users and ask to expand the addresses and embed the schedules
http://localhost:3000/users?_expand=addresses&_embed=schedules
I am able to filter all of the user stories based on a start Release and an end Release, but I now want to group these user stories based on the specific Release they are in. For example, If my start Release is 35 and my end Release is 37, I want to take all the user stories I got from the code below and save them into 35, 36, and 37 based on where they reside. I was thinking if there was a way to loop through each release between two dates and save the data as I go, it would work.
// Filters all user stories between start release date and end release date
var iterationFilters = [
{
property: 'Iteration.StartDate',
operator: '>=',
value: StartDate
},
{
property: 'Iteration.EndDate',
operator: '<=',
value: EndDate
},
];
var defectStore = Ext.create('Rally.data.wsapi.Store', {
model: 'User Story',
autoLoad: true,
filters : iterationFilters,
listeners: {
load: function(myStore, myData) {
console.log(myData)
},
scope: this
},
fetch: ['CreationDate','FormattedID']
});
}
Is the intent to show it in a grid? If so you could use this example to get you pretty close: https://help.rallydev.com/apps/2.1/doc/#!/example/groupable-grid
Otherwise if you just need to manipulate the raw data, I'd just use the groupBy function provided by lodash.
var storiesByRelease = _.groupBy(defectStore.getRange(), function(story) {
return story.get('Release')._refObjectName;
});
I've been playing around storing tweets inside mongodb, each object looks like this:
{
"_id" : ObjectId("4c02c58de500fe1be1000005"),
"contributors" : null,
"text" : "Hello world",
"user" : {
"following" : null,
"followers_count" : 5,
"utc_offset" : null,
"location" : "",
"profile_text_color" : "000000",
"friends_count" : 11,
"profile_link_color" : "0000ff",
"verified" : false,
"protected" : false,
"url" : null,
"contributors_enabled" : false,
"created_at" : "Sun May 30 18:47:06 +0000 2010",
"geo_enabled" : false,
"profile_sidebar_border_color" : "87bc44",
"statuses_count" : 13,
"favourites_count" : 0,
"description" : "",
"notifications" : null,
"profile_background_tile" : false,
"lang" : "en",
"id" : 149978111,
"time_zone" : null,
"profile_sidebar_fill_color" : "e0ff92"
},
"geo" : null,
"coordinates" : null,
"in_reply_to_user_id" : 149183152,
"place" : null,
"created_at" : "Sun May 30 20:07:35 +0000 2010",
"source" : "web",
"in_reply_to_status_id" : {
"floatApprox" : 15061797850
},
"truncated" : false,
"favorited" : false,
"id" : {
"floatApprox" : 15061838001
}
How would I write a query which checks the created_at and finds all objects between 18:47 and 19:00? Do I need to update my documents so the dates are stored in a specific format?
Querying for a Date Range (Specific Month or Day) in the MongoDB Cookbook has a very good explanation on the matter, but below is something I tried out myself and it seems to work.
items.save({
name: "example",
created_at: ISODate("2010-04-30T00:00:00.000Z")
})
items.find({
created_at: {
$gte: ISODate("2010-04-29T00:00:00.000Z"),
$lt: ISODate("2010-05-01T00:00:00.000Z")
}
})
=> { "_id" : ObjectId("4c0791e2b9ec877893f3363b"), "name" : "example", "created_at" : "Sun May 30 2010 00:00:00 GMT+0300 (EEST)" }
Based on my experiments you will need to serialize your dates into a format that MongoDB supports, because the following gave undesired search results.
items.save({
name: "example",
created_at: "Sun May 30 18.49:00 +0000 2010"
})
items.find({
created_at: {
$gte:"Mon May 30 18:47:00 +0000 2015",
$lt: "Sun May 30 20:40:36 +0000 2010"
}
})
=> { "_id" : ObjectId("4c079123b9ec877893f33638"), "name" : "example", "created_at" : "Sun May 30 18.49:00 +0000 2010" }
In the second example no results were expected, but there was still one gotten. This is because a basic string comparison is done.
To clarify. What is important to know is that:
Yes, you have to pass a Javascript Date object.
Yes, it has to be ISODate friendly
Yes, from my experience getting this to work, you need to manipulate the date to ISO
Yes, working with dates is generally always a tedious process, and mongo is no exception
Here is a working snippet of code, where we do a little bit of date manipulation to ensure Mongo (here i am using mongoose module and want results for rows whose date attribute is less than (before) the date given as myDate param) can handle it correctly:
var inputDate = new Date(myDate.toISOString());
MyModel.find({
'date': { $lte: inputDate }
})
Python and pymongo
Finding objects between two dates in Python with pymongo in collection posts (based on the tutorial):
from_date = datetime.datetime(2010, 12, 31, 12, 30, 30, 125000)
to_date = datetime.datetime(2011, 12, 31, 12, 30, 30, 125000)
for post in posts.find({"date": {"$gte": from_date, "$lt": to_date}}):
print(post)
Where {"$gte": from_date, "$lt": to_date} specifies the range in terms of datetime.datetime types.
db.collection.find({"createdDate":{$gte:new ISODate("2017-04-14T23:59:59Z"),$lte:new ISODate("2017-04-15T23:59:59Z")}}).count();
Replace collection with name of collection you want to execute query
MongoDB actually stores the millis of a date as an int(64), as prescribed by http://bsonspec.org/#/specification
However, it can get pretty confusing when you retrieve dates as the client driver will instantiate a date object with its own local timezone. The JavaScript driver in the mongo console will certainly do this.
So, if you care about your timezones, then make sure you know what it's supposed to be when you get it back. This shouldn't matter so much for the queries, as it will still equate to the same int(64), regardless of what timezone your date object is in (I hope). But I'd definitely make queries with actual date objects (not strings) and let the driver do its thing.
Use this code to find the record between two dates using $gte and $lt:
db.CollectionName.find({"whenCreated": {
'$gte': ISODate("2018-03-06T13:10:40.294Z"),
'$lt': ISODate("2018-05-06T13:10:40.294Z")
}});
Using with Moment.js and Comparison Query Operators
var today = moment().startOf('day');
// "2018-12-05T00:00:00.00
var tomorrow = moment(today).endOf('day');
// ("2018-12-05T23:59:59.999
Example.find(
{
// find in today
created: { '$gte': today, '$lte': tomorrow }
// Or greater than 5 days
// created: { $lt: moment().add(-5, 'days') },
}), function (err, docs) { ... });
db.collection.find({$and:
[
{date_time:{$gt:ISODate("2020-06-01T00:00:00.000Z")}},
{date_time:{$lt:ISODate("2020-06-30T00:00:00.000Z")}}
]
})
##In case you are making the query directly from your application ##
db.collection.find({$and:
[
{date_time:{$gt:"2020-06-01T00:00:00.000Z"}},
{date_time:{$lt:"2020-06-30T00:00:00.000Z"}}
]
})
You can also check this out. If you are using this method, then use the parse function to get values from Mongo Database:
db.getCollection('user').find({
createdOn: {
$gt: ISODate("2020-01-01T00:00:00.000Z"),
$lt: ISODate("2020-03-01T00:00:00.000Z")
}
})
Save created_at date in ISO Date Format then use $gte and $lte.
db.connection.find({
created_at: {
$gte: ISODate("2010-05-30T18:47:00.000Z"),
$lte: ISODate("2010-05-30T19:00:00.000Z")
}
})
use $gte and $lte to find between date data's in mongodb
var tomorrowDate = moment(new Date()).add(1, 'days').format("YYYY-MM-DD");
db.collection.find({"plannedDeliveryDate":{ $gte: new Date(tomorrowDate +"T00:00:00.000Z"),$lte: new Date(tomorrowDate + "T23:59:59.999Z")}})
mongoose.model('ModelName').aggregate([
{
$match: {
userId: mongoose.Types.ObjectId(userId)
}
},
{
$project: {
dataList: {
$filter: {
input: "$dataList",
as: "item",
cond: {
$and: [
{
$gte: [ "$$item.dateTime", new Date(`2017-01-01T00:00:00.000Z`) ]
},
{
$lte: [ "$$item.dateTime", new Date(`2019-12-01T00:00:00.000Z`) ]
},
]
}
}
}
}
}
])
For those using Make (formerly Integromat) and MongoDB:
I was struggling to find the right way to query all records between two dates. In the end, all I had to do was to remove ISODate as suggested in some of the solutions here.
So the full code would be:
"created": {
"$gte": "2016-01-01T00:00:00.000Z",
"$lt": "2017-01-01T00:00:00.000Z"
}
This article helped me achieve my goal.
UPDATE
Another way to achieve the above code in Make (formerly Integromat) would be to use the parseDate function. So the code below will return the same result as the one above :
"created": {
"$gte": "{{parseDate("2016-01-01"; "YYYY-MM-DD")}}",
"$lt": "{{parseDate("2017-01-01"; "YYYY-MM-DD")}}"
}
⚠️ Be sure to wrap {{parseDate("2017-01-01"; "YYYY-MM-DD")}} between quotation marks.
Convert your dates to GMT timezone as you're stuffing them into Mongo. That way there's never a timezone issue. Then just do the math on the twitter/timezone field when you pull the data back out for presentation.
Why not convert the string to an integer of the form YYYYMMDDHHMMSS? Each increment of time would then create a larger integer, and you can filter on the integers instead of worrying about converting to ISO time.
Scala:
With joda DateTime and BSON syntax (reactivemongo):
val queryDateRangeForOneField = (start: DateTime, end: DateTime) =>
BSONDocument(
"created_at" -> BSONDocument(
"$gte" -> BSONDateTime(start.millisOfDay().withMinimumValue().getMillis),
"$lte" -> BSONDateTime(end.millisOfDay().withMaximumValue().getMillis)),
)
where millisOfDay().withMinimumValue() for "2021-09-08T06:42:51.697Z" will be "2021-09-08T00:00:00.000Z"
and
where millisOfDay(). withMaximumValue() for "2021-09-08T06:42:51.697Z" will be "2021-09-08T23:59:99.999Z"
i tried in this model as per my requirements i need to store a date when ever a object is created later i want to retrieve all the records (documents ) between two dates
in my html file
i was using the following format mm/dd/yyyy
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<script>
//jquery
$(document).ready(function(){
$("#select_date").click(function() {
$.ajax({
type: "post",
url: "xxx",
datatype: "html",
data: $("#period").serialize(),
success: function(data){
alert(data);
} ,//success
}); //event triggered
});//ajax
});//jquery
</script>
<title></title>
</head>
<body>
<form id="period" name='period'>
from <input id="selecteddate" name="selecteddate1" type="text"> to
<input id="select_date" type="button" value="selected">
</form>
</body>
</html>
in my py (python) file i converted it into "iso fomate"
in following way
date_str1 = request.POST["SelectedDate1"]
SelectedDate1 = datetime.datetime.strptime(date_str1, '%m/%d/%Y').isoformat()
and saved in my dbmongo collection with "SelectedDate" as field in my collection
to retrieve data or documents between to 2 dates i used following query
db.collection.find( "SelectedDate": {'$gte': SelectedDate1,'$lt': SelectedDate2}})
I have the following JSON Object, which is the result of a loopback model (Classifications), with a relationship with another model (Labels).
My call to get the classifications is:
modClassification.findOne({
where: { id: classificationid },
include: 'labels' },
function( err, classification ){ ...
And this returns classification with something like
{ id: 'b01',
title: 'population',
country_id: 1,
labels:
[ { column_id: 'b1',
classification_id: 'b01',
classification_title: 'population',
dsporder: 1,
label: 'Total_Persons_Males',
country_id: 1,
id: 1 },
{ column_id: 'b2',
classification_id: 'b01',
classification_title: 'population',
dsporder: 2,
label: 'Total_Persons_Females',
country_id: 1,
id: 2 } ] }
which is what I would expect.
I now need to loop over the labels and access it's properties, but this is where I am stuck.
classification.labels[0] = undefined..
I have tried looping, each and whatever I can find online, but can't seem to get to each labels properties.
Can someone tell me what I am doing wrong/need to do?
Thanks
When you are including related models inside a findOne call, you need to JSONify the result before accessing the related records:
classification = classification.toJSON()
Then you should be able to access the included label items as you expect.
See https://docs.strongloop.com/display/public/LB/Include+filter, specifically the "Access included objects" section.
Note this does not work the same when you retrieve more than one result in an array. In that case you'll need to perform toJSON() on each item in the array.