1

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?

Community
  • 1
  • 1
  • All of this is predicated on the idea that your database contains the required users. What evidence do you have that suggests that it does? Furthermore, are your publishing any of them to the client? The way your question is phrased, it sounds like `Meteor.users.find().count()` would return `1` on the client, and that one record is outside of your date range. – David Weldon Nov 05 '15 at 16:21
  • Thats becoz I have manually inputted a test record into the database with birthday fall within the age range of 18-22. '{"_id": 123452345, "profile.birthday": ISODATE("1975-10-22T00:00:00Z")}'. But I cannot get the format of the query right to return this record. – frankcheong Nov 06 '15 at 02:06
  • And the problem is I cannot locate this record on the server mongodb shell as well and thus I am pretty sure the problem is with the query itself. – frankcheong Nov 06 '15 at 02:49

2 Answers2

0

Hint:

Try the following query format in the mongodb shell.

db.users.find( 
    {"profile.birthday":{ 
        $gte: ISODate(fromAge),
        $lt: ISODate(toAge)
    }
})

fromAge and toAge should be proper format.

Abdullah Rasheed
  • 3,562
  • 4
  • 33
  • 51
  • Does that means putting var fromAge=new Date(new Date().setYear(new Date().getFullYear() - 18)); var toAge=new Date(new Date().setYear(new Date().getFullYear() - 22)); db.users.find({"profile.birthday":{$gte: ISODate(toAge.toISOString()), $lt: ISODate(fromAge.toISOString())}}); – frankcheong Nov 06 '15 at 02:09
  • @frankcheong when you do a query like this: `db.users.find()` in the mongoshell what are the results? – Abdullah Rasheed Nov 06 '15 at 13:53
  • in mongoshell doing db.users.find() did return a lot of records including my target record. I have find that I need to use Date in my meteor app and Meteor will do the Date to ISODate conversion. While my problem is I have a lot of dropdown each of which constitute part of the query. All dropdown works fine while I didn't able to get the dropdown work for this age range. – frankcheong Nov 09 '15 at 15:28
0

From another forum I got an answer.

For details please refer to https://forums.meteor.com/t/meteor-db-find-with-date-inside-a-json-as-selector-not-working/12892/9

In short, I just new a Date Object in the query like that

query[DBPrefix] = {
  $lte: new Date(fromDate),
  $gte: new Date(toDate)
}