MongoId perform day / month specific queries on the date - mongodb

I am using MongoId 3,Rails 3.2 ,Ruby 1.9.3.
I wanted to query only part of a date, such as the day, week or month.
So for example, let's say we need to find all users that signed up on a Wednesday OR
get all users whose birthday is on 25 day Or get all users who born in April month(not specific to particular year here) etc..
In Mysql we have select * from users where extract(dow from created_at) = 3;
But how can we perform this using MongoId.

Here is a pretty handy cookbook on querying data ranges on Mongodb: http://cookbook.mongodb.org/patterns/date_range/ . and you can just create the query almost in the same way on Mongoid, using .where

I think the aggregation framework is a better fit for this. This question discusses the use of date operators in aggregation.
I've not had much experience with Mongoid, but it seems like it should support aggregation just fine, as long as you are using a recent version.

Related

Firestore query with inequality filters on multiple fields

I am building a calendar on IOS using Swift, with a Firestore back-end.
I am retrieving all the events for each day in a month at one time.
Currently I can only display events that start on a particular day.
This is no good if an event starts on a Friday night and ends on a Monday morning (think, weekend on holiday).
so...
I need to get all the Event documents from Firestore where the day currently being populated with events sits between the timestamps of the start and end fields on the Firestore document.
The obvious first choice is something like this:
db.collection("Event")
.whereField("user", isEqualTo: userID)
.whereField("start", isLessThanOrEqualTo: thisDate)
.whereField("end", isGreaterThanOrEqualTo: thisDate)
.getDocuments()
but it turns out Firebase won't let me run 2 inequality filters on different fields [:(
The only other option I can think of is to get all the events that started before today, scan through each one and check if it ended before today, then display the rest.
But this doesn't seem very efficient, especially if you think about 5 years down the line when a user might have an event for every day of the year (that's A LOT of documents to check through in a short space of time).
Does anybody have any suggestions as to how I might do this?
Thanks :)
UPDATE
I forgot to add this in, It's a screenshot of how the database is structured :)
(note that day, month, and year are obsolete fields now that I have started using timestamps)
Firestore has query limitations that allow inequality filters only on the same field:
In a compound query, range (<, <=, >, >=) and not equals (!=, not-in)
comparisons must all filter on the same field.
Unfortunately, it doesn't look like something that could be changed on the Google side because there were certain reasons for implementing the current design, for instance, the query speed.
In this case, you will need to use the solution that you've came up with in your code.
One solution we have used (not great but works) is time selectors. You need to add 'time selectors' to your model e.g.
const event = {
...baseEvent,
timeSelector: {
isoDay: 'yyyy-mm-dd',
isoWeek: 'kkkk-WW', // luxon format
isoMonth: 'yyyy-mm'
}
}
then depending on how wide your time interval is you can use array 'in' operator
db.collection("Event")
.where('timeSelector.isoWeek', 'in', ['1999-01', '1999-02'])
That will greatly reduce the amount of documents pulled client side, however an extra client side filtering will be required, and playing with time intervals is always fun

Firestore creating a representation of a order form

I'm new at firebase/firestore. Appreciate your thoughts on this.
I'm trying to create an order form using Firestore.
I was wondering:
Do I need to create a YEAR, MONTH, DATE of collections and documents just to save all the order forms ?
This felt redundant to me, otherwise a lot of databases in Firestore will require a lot of collections and documents of dates!
E.g.:
(CAPS is Collection, bracketed are the documents)
YEAR (2018) -> MONTH (Jan, Feb, Mar, etc)
JAN -> 1 (order #1, order #2, order #3, etc)
JAN -> 2 (order #1, order #2, etc...)
Or just a simple time stamp on each document of order form - and then if I want to look up say for the month of January, is there a search query to look up all the documents in a specific month? or date?
And as order forms go, the user can enter as many items as possible. Is it correct to have each item stored as a new document? Therefore possibly creating 100+ documents per collection of order form.
E.g.:
order 1 collection - banana document, apple document, orange document
There is no single best data model. It all depends on the use-cases of your app. For a general introduction to this domain, I recommend reading NoSQL data modeling.
But in Firestore having a collection with many documents is not a concern. The database was made to scale to almost any number of documents.
You'll indeed want to store a timestamp in each order. The best way for this is like to use a server-side timestamp. You can then query for orders in a given date range with a query like this:
var now = new Date();
var yesterday = new Date(Date.now() - 24*60*60*1000);
ordersRef.where("timestamp", ">=", yesterday).where("timestamp", "<=", now)
Or
ordersRef.where("timestamp", ">=", "2017-01-01").where("timestamp", "<=", "2017-12-31")
For more examples, see the Firestore documentation on queries.

Group by weeks in Mongodb where dates are fixed (1-7, 8-14, 15-21, 22-28, 29-31)

I am looking for a way to group my data which has a column with datetime in it.
I want to group it such that, the business requirement is to have the records by a fixed week definition of (1-7, 8-14, 15-21, 22-28, 29-31).
While MongoDB $week would group by calendar weeks.
Any idea how to go about this custom grouping?

neo4j 2.0 / cypher searching by date

I have looked at previous SO questions about using neo4j with dates and this blog post
http://blog.nigelsmall.com/2012/09/modelling-dates-in-neo4j.html
I'm not exactly sure how to get this to work however. Basically I need two things, to add a date to a node and then to query nodes by date.
As an example of something similar to what I like, imagine I have the movie The Matrix in my graph. Text examples for queries that should include then the movie The Matrix:
Movies released in Q1, 1999
Movies relased on March 31, 1999
Movies released in March 1999
Movies released before 2000
Movies released between 1998 and 20000
What I've tried for now as a start is building the date graph as described in the blog post. I tried with the following query, but I guess it's not constructed correctly
CREATE UNIQUE p = (CAL)-[:YEAR]->(1999 { number:1999 })-[:QUARTER]->(1 { number:1} )-[:MONTH]->(3 { number:3})-[:DAY]->(31 { number:31}) return p;
I guess then after I've made a node for a specific date, I would add a released_on->(that_date) to The Matrix.
So now I'm wondering if this is the way to go for the kind of queries I'd like to do, and how to actually make it work.
If those are the only queries you are planning to do, I would say that a property and an index query might be a better idea.
For each movie, you add a date property as a string in the following format : YYYYMMDD
You can then query for a specific date from a date_index, or have where conditions like : > 19990101 and <19990401 for the first quarter of 1999.
There are of course few shortcomings with this approach, one that comes to my mind being that you can't get movies by "seasonality", say for examples all summer movies for all the years ! In this, the in graph data index is a better idea.
I ended up putting the dates in the graph in a similar way to what is described in the blog post.
To add a date I use the following query:
MERGE (n0:Calendar) CREATE UNIQUE (n0)-[r0:YEAR]->(n1 {number: 2003})-[:QUARTER]->(q { number: 1} )-[r1:MONTH]->(n2 {number: 3})-[r2:DAY]->(n3 {number: 31}) RETURN n3;
Then I use queries similar to this to get nodes and their dates:
MATCH (r)-[:has_date]->(day)<-[:DAY]-(month)<-[:MONTH]-(quarter)<-[:QUARTER]-(year) return day,month,quarter,year;

sqlite3: retrieving data based on month and year from local database in iphone

In my application I have to store data month wise and year wise. So for this, I have to store the data along with date into database.
My requirement is how to store in terms of date and how to retrieve data with group by month and year. In my app I am showing a table of years and months, based on selected month and year. I have to show the data in a dashboard.
My problem is in storing and retrieving date data types.
Use the following syntax
SELECT * FROM DATABASE WHERE REQUIREDDATEFIELD LIKE '%2011-01%';
2011 is supposed to be the year
01 is supposed to be the month
DATABASE is supposed to be your mysql database name
REQUIREDDATEFIELD is supposed to be the field you are hoping to sort from month and year.
like '%2011-01%' is supposed to be meaning, all the records containing 2011-01 in the given field. It could be in the beginning or the end or in the middle of a large text, so having % in both the beginning and end of the search criteria is a good habit.
You just select either for a specific month or year or month and year. Or if you want all, you use GROUP BY.
I know this answer is quite vague and generic, but that's because your question is vague. You probably need to be more specific. Explain not only what you want to do, but what you have tried, and in which way that didn't work.