【问题标题】:Meteor db.find with Date inside a json as selector not workingMeteor db.find 在 json 中使用 Date 作为选择器不起作用
【发布时间】:2016-02-06 13:20:33
【问题描述】:

我阅读了互联网上的大量资源,并遵循了很多关于如何在特定日期范围内查找收藏的示例,但没有奏效。我的代码如下:-

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();

当我执行一个简单的 Meteor.users.find().fetch() 时,上面的查询返回一个空集合,它确实返回了以下一条记录:-

{"_id": 123452345, "profile.birthday": ISODATE("1975-10-22T00:00:00Z")}

为了调试,我还在 javascript 控制台和后端服务器 mongo shell 上编写了以下查询,它也确实返回了空集合。

Javascript 控制台

Meteor.users.find({"profile.birthday": {$lt: new Date()}})

服务器 MongoDB 外壳

db.users.find{"profile.birthday": {$lt: new Date()}})

我现在不知道。如果有人能启发我,那就太好了。

-- 更新--

我尝试了以下查询,但它确实没有返回任何内容

db.users.find({"profile.birthday":{$lt: new Date(new Date().setYear(new Date().getFullYear() - 18)).toISOString()}})

我在 javascript 控制台中输入了命令

new Date(new Date().setYear(new Date().getFullYear() - 18)).toISOString()

它确实告诉了我

"1997-11-06T16:35:28.844Z"

在我的数据库中,生日的记录应该是“1975-10-22T00:00:00Z”,因此它应该达到这个记录,但我只能拥有一个空集合。

有人告诉我使用 ISODate(),我尝试了以下命令,它在 MongoDB Shell 中确实有效,而它在我的 Meteor 辅助函数中产生 ISODate Undefined。

db.users.find({"profile.birthday":{$lt: ISODate("1977-11-06")})

通过阅读其他一些资源 (Inserting and Querying Date with MongoDB and Nodejs) 并了解到我应该使用 Date 而不是 ISODate,因为 ISODate 是 MongoDB 内部的,而 Meteor 将有助于进行 Date 到 ISODate 的转换。然后我尝试对查询进行硬编码,它确实工作正常:-

db.users.find({"profile.birthday": {$lt: new Date("1977-11-06T00:00:00.000Z")}})

-- 更新开始(2015 年 11 月 16 日)--

它工作正常,而我的问题是我尝试在 json 中构建选择器,然后将其放入 find 中,而这不起作用:-

selector={"profile.birthday": {$lt: new Date("1977-11-06T00:00:00:000Z"}};
db.users.find(selector);

上面的查询什么也没返回。

-- 更新结束(2015 年 11 月 16 日)--

我这样做是因为我有一个年龄组下拉列表,并且正在尝试通过辅助事件构建查询。我在下面有一个下拉模板:- /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>

还有下面的助手

/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}});
    }
  }
}

服务器/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;
      }
    }
});

逻辑是这样的,实际上我有很多下拉列表,每个下拉列表都将构成查询的一部分,我使用实例反应变量设置查询,这样每当它发生变化时,meteor 都会再次执行meteor.find。除了这个生日是一个日期之外,每个下拉菜单都可以正常工作。有人知道出了什么问题吗?

【问题讨论】:

  • 所有这些都基于您的数据库包含所需用户的想法。你有什么证据表明它确实如此?此外,您是否将其中任何一个发布给客户?您的问题的措辞方式听起来像Meteor.users.find().count() 会在客户端返回1,并且一条记录超出了您的日期范围。
  • 那是因为我手动在数据库中输入了一条生日在 18-22 岁范围内的测试记录。 '{"_id": 123452345, "profile.birthday": ISODATE("1975-10-22T00:00:00Z")}'。但是我无法获取返回该记录的查询格式。
  • 问题是我也无法在服务器 mongodb shell 上找到这条记录,因此我很确定问题出在查询本身。

标签: javascript mongodb meteor


【解决方案1】:

提示:

在 mongodb shell 中尝试以下查询格式。

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

fromAgetoAge 应该是正确的格式。

【讨论】:

  • 这是否意味着将 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 当您执行这样的查询时:db.users.find() 在 mongoshell 中的结果是什么?
  • 在 mongoshell 中执行 db.users.find() 确实返回了很多记录,包括我的目标记录。我发现我需要在我的流星应用程序中使用日期,流星将执行日期到 ISODate 的转换。虽然我的问题是我有很多下拉列表,每个下拉列表都构成查询的一部分。所有下拉菜单都可以正常工作,而我无法为这个年龄段的下拉菜单工作。
【解决方案2】:

我从另一个论坛得到了答案。

详情请参考https://forums.meteor.com/t/meteor-db-find-with-date-inside-a-json-as-selector-not-working/12892/9

简而言之,我只是在这样的查询中新建一个日期对象

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-01
    • 2015-06-05
    • 2013-02-08
    相关资源
    最近更新 更多