Javascript 为什么$elemMatch MongoDB查询在具有扩展RexExp EJSON类型的客户端和服务器上表现不同?

Javascript 为什么$elemMatch MongoDB查询在具有扩展RexExp EJSON类型的客户端和服务器上表现不同?,javascript,regex,mongodb,meteor,coffeescript,Javascript,Regex,Mongodb,Meteor,Coffeescript,这是一个非常特殊的案例,但对于任何想要利用MongoDB的RegExp功能强大的查找(使用Meteor中的发布和订阅从客户机(Mini Mongo)到服务器(MongoDB))的人来说都非常相关我想了解为什么服务器和客户端MongoDB查询功能之间存在差异,并在a)需要和B)对其他开发人员有利的情况下开发对Meteor的拉取请求。 I.一般情况: 至少使用aldeed:Meteor简单模式、aldeed:collection2、帐户密码和ejson运行Meteor安装 扩展EJSON,方法是使用

这是一个非常特殊的案例,但对于任何想要利用MongoDB的
RegExp
功能强大的查找(使用Meteor中的发布和订阅从客户机(Mini Mongo)到服务器(MongoDB))的人来说都非常相关我想了解为什么服务器和客户端MongoDB查询功能之间存在差异,并在a)需要和B)对其他开发人员有利的情况下开发对Meteor的拉取请求。

I.一般情况:

  • 至少使用
    aldeed:Meteor简单模式
    aldeed:collection2
    帐户密码
    ejson
    运行Meteor安装
  • 扩展
    EJSON
    ,方法是使用
    EJSON.addType
    和以下说明添加
    RegExp
    类型:
  • 添加电子邮件地址为“
    ”的Meteor.user”admin@foo.com“
  • 在Meteor服务器上运行此代码(意外结果)

    # anywhere on the server
    if Meteor.isServer
      user_selector = { 'emails': { '$elemMatch': { 'address': /^adm/ } } }
      user_count = Meteor.users.find(user_selector).count()
      console.log user_count 
      # prints 0 WHY!?
    
    # anywhere on the server
    if Meteor.isServer
      user_selector = { 'emails': { '$elemMatch': { 'address': /^adm/ } } }
      user_count = MyUsers.find(user_selector).count()
      console.log user_count 
      # prints 0 WHY!?
    
  • 在MongoDB shell上运行此命令(绕过Meteor.users):

  • 尝试使用相同的数据进行独立的Mongo.Collection查找

    # server
    MyUsers = new Mongo.Collection 'myusers'
    
  • 将用户文档从Meteor.users()复制到MyUsers集合中

  • 在Meteor服务器上运行此操作(也是意外的)

    # anywhere on the server
    if Meteor.isServer
      user_selector = { 'emails': { '$elemMatch': { 'address': /^adm/ } } }
      user_count = Meteor.users.find(user_selector).count()
      console.log user_count 
      # prints 0 WHY!?
    
    # anywhere on the server
    if Meteor.isServer
      user_selector = { 'emails': { '$elemMatch': { 'address': /^adm/ } } }
      user_count = MyUsers.find(user_selector).count()
      console.log user_count 
      # prints 0 WHY!?
    
  • 此外,如果我发布所有用户,但对客户端代码运行完全相同的查询(例如,在模板助手参数中),则查询将返回预期的计数

    II。发布/订阅模板辅助案例:

    • 发布和订阅用户

      # Server
      Meteor.publish 'all_users', ->
        return Meteor.users.find({})
      
      # Client
      Template.people.onCreated ->
        self = @
        self.peopleReady = new ReactiveVar()
        self.autorun ->
          users = Meteor.subscribe 'all_users'
          self.peopleReady.set users.ready()
      
      Template.people.helpers
        user_count: ->
          user_selector = { 'emails': { '$elemMatch': { 'address': /^adm/ } } }
          user_count = Meteor.users.find(user_selector).count()
          console.log user_count 
          # prints 1
          return user_count         
      
    为什么上面的I.4中显示了服务器代码的差异?我想知道是因为

    • EJSON被适当地扩展
    • MiniMongo正确选择和统计客户机上的记录
    • 使用MyUser集合(用Mongo.Collection实例化)也无法报告服务器上的正确计数,但使用此查询选择器中的扩展RegExp EJSON类型在客户端上成功运行与Meteor.user范围之外的相同文档

    在Meteor源代码中,我在哪里可以看到(并试验)Collection.find()的服务器端定义?

    这看起来确实像一个bug。请将问题提交至。请务必遵循我们的复制指导原则。

    在服务器上使用meteor shell会话对我来说似乎很好。您可以尝试使用
    $regex
    操作符而不是java脚本表达式吗。它可能是某个地方记录的bug。@Batshray-不,在数组查找中,$regex运算符不起作用(例如,
    '$in':[/foo/gi,/bar/gi,'baz']
    ),因此这不是一个选项。还要注意,EJSON类型已正确扩展,并且在客户端工作良好。无论如何,我都想修复这个错误。你试过$elemMatch吗?不带$in。@BatScream-是的,这是OP中的例子。RegExp需要对两者都起作用。在处理任何错误报告之前,我正在深入研究这个问题,并为我们的业务案例制定解决方案。感谢您花时间通读并提出建议!我已经开始正式记录这个问题。我也打算解决这个问题,但我的带宽有限。现在,我已经修补了我们的Meteor代码以绕过这个问题并部署到Galaxy。