I read thru a lot of resources in the internet and followed a lot of examples on how to find a collection within a specific date range and it didn't work. My code is as below:-
var fromAge = 18;
var toAge = 22;
Meteor.users.find({:profile.birthday":{$lt: new Date(new Date().setYear(new Date().getFullYear() - fromAge)), $gt: new Date(new Date().setYear(new Date().getFullYear() - toAge))}).fetch();
The above query return an empty collection when I do a simple Meteor.users.find().fetch() it did returned one record below:-
{"_id": 123452345, "profile.birthday": ISODATE("1975-10-22T00:00:00Z")}
to debug, I also write the following query on both javascript console as well as backend server mongo shell and it did return empty collection as well.
Javascript Console
Meteor.users.find({"profile.birthday": {$lt: new Date()}})
Server MongoDB Shell
db.users.find{"profile.birthday": {$lt: new Date()}})
I have no clue now. It would be great if somebody can enlighten me.
-- UPDATE --
I tried the below query and it did return nothing
db.users.find({"profile.birthday":{$lt: new Date(new Date().setYear(new Date().getFullYear() - 18)).toISOString()}})
I typed in the command in javascript console
new Date(new Date().setYear(new Date().getFullYear() - 18)).toISOString()
And it did tell me
"1997-11-06T16:35:28.844Z"
And it my database, the record the birthday should be "1975-10-22T00:00:00Z" and thus it should hit this record, but all I can have is an empty collection.
Someone tells me to use ISODate(), I tried the below command it did works in MongoDB Shell, while it yields ISODate Undefined in my Meteor helper function.
db.users.find({"profile.birthday":{$lt: ISODate("1977-11-06")})
Have read thru some other resources (Inserting and Querying Date with MongoDB and Nodejs) and learnt that I should use Date instead of ISODate whereby ISODate is internal to MongoDB and Meteor will help to do the Date to ISODate Conversion. I then tried to hard code the query and it did works fine:-
db.users.find({"profile.birthday": {$lt: new Date("1977-11-06T00:00:00.000Z")}})
-- UPDATE BEGIN (16 Nov 2015) --
It works fine, while my problem is I tried to build the selector in json and then put it into the find while this wont work:-
selector={"profile.birthday": {$lt: new Date("1977-11-06T00:00:00:000Z"}};
db.users.find(selector);
The above query returned nothing at all.
-- UPDATE END (16 Nov 2015) --
I am doing that because I have a dropdown of age group and am trying to build the query thru a helper event. I have a dropdown template below:- /client/ageRangeDropdown.html
<template name="AgeRangeDropdown">
<div class="btn-group">
Age Group
<select id="ageRangeDropdownList" class="form-control">
<option >Whatever</option>
<option >18-22</option>
<option >23-27</option>
<option >28-32</option>
<option >33-37</option>
<option >38-42</option>
<option >43-47</option>
<option >48-52</option>
<option >53-57</option>
</select>
</div>
{{#each currentCriterias}}
<span class="label label-info">{{criteria}}</span>
{{/each}}
{{#each myUser}}
{{profile.firstName}} , {{profile.lastName}}, {{profile.birthday}}
{{/each}}
</template>
And the helper below
/client/ageRangeDropdown.js
Template.ageRangeDropdown.events({
'change ageRangeDropdownList': function(e) {
for (var key in target) {
if (!target.hasOwnProperty(key)) {
if (key=='id') {
id = target[key];
}
}
}
var value = target.options[target.selectedIndex].value;
if (value!='Whatever') {
currentCriterias.push({id: "profile.birthday", criteriaValue: value});
}
var query = [];
for (var i = 0; i < items.length; i++) {
var itemObject = {};
var fromAge = currentCriterias[i]['criteriaValue'].substr(0,2);
var toAge = currentCriterias[i]['criteriaValue'].substr(3,2);
itemObject['profile.birthday'] = {
$gt: new Date(new Date().setYear(new Date().getFullYear() - fromAge)),
$lt: new Date(new Date().setYear(new Date().getFullYear() - toAge))
}
query.push(itemObject);
}
var selector = [];
selector.push({$or: query});
Template.instance().selector.set({$or: selector});
return false;
})
Templage.ageRangeDropdown.created = function() {
var instance = this;
instance selector = new RactiveVar([]);
instance.autorun(function() {
var selector = instance.selector.get();
if (typeof selector != 'undefined' && Object.keys(selector).length > 0) {
var subscription = instance.subscribe('searchUser', selector);
}
});
instance.myUser = function() {
var selector = instance.selector.get();
if (typeof selector != 'undefined' && Object.keys(selector).length > 0) {
return Meteor.users.find(selector, {fields: {profile: 1}});
}
}
}
server/serverpublish.js
Meteor.publish("searchUser", function(selector){
if (!this.userId) {
console.log("Cannot search User when you haven't logged in.");
return null;
} else {
if (typeof selector != 'undefined' || Object.keys(selector).length > 0) {
var user=Meteor.users.find(selector, {fields: {profile: 1}});
return user;
} else {
console.log("won't publish all user profiile when no selector is given");
return null;
}
}
});
The logic is like that, actually I have a lot of dropdown each of which will constitute part of the query, and I setup the query using instance reactive variable so that whenever it changed, meteor will do a meteor.find again. Every dropdown works fine except this birthday which is a date. Anyone have idea what's going wrong?