Meteor:将Mongo Selector从客户端传递到服务器的最佳方法

Ada*_*dam 2 javascript mongodb meteor

我有一个类似下面的mongo集合(Foo(X)== keys; Bars == values):编辑 - 我来自关系数据库背景.显然我的收藏品看起来不像下面那样,但你明白了......

+--------+--------+--------+
|  Foo1  |  Foo2  |  Foo3  |
+--------+--------+--------+
| Barbar | Barbar |   Bar  |
|   bar  |  Bar   | BarBar |
|   Bar  | barbar | barBar |
|   ...  |   ...  |   ...  |
Run Code Online (Sandbox Code Playgroud)

允许我的客户端过滤数据对我来说很重要.有时候,所有列都会有一个过滤器,有时候没有列会有过滤器,而且介于两者之间.目前,我正在处理以下问题:

客户

Var aFoo1Filter = ["bar"]
Var aFoo2Filter = ["Barbar", "BarBar"]
Var aFoo3Filter = ["barbar", "bar"]
//Where the user can affect the array through some other code
Run Code Online (Sandbox Code Playgroud)

服务器

Meteor.publish("foos", function (aFoo1Filter, aFoo2Filter, aFoo3Filter ) {
  return FooCl.find({Foo1: {$in: aFoo1Filter},
                     Foo2: {$in: aFoo2Filter},
                     Foo3: {$in: aFoo3Filter}}, 
                    {limit: 10});
});
Run Code Online (Sandbox Code Playgroud)

我希望通过从客户端到服务器只传递一个对象或一个字符串来简化这一过程,但这两种尝试都没有奏效.看看我的尝试,如下:

尝试#1 - 通过字符串

客户

Var sFilter = "Foo1: {$in: [\"bar\"]},
               Foo2: {$in: [\"Barbar\", \"BarBar\"]},
               Foo3: {$in: [\"barbar\", \"bar\"]}"
Run Code Online (Sandbox Code Playgroud)

服务器

Meteor.publish("foos", function (sFilter) {
  return FooCl.find({sFilter}, 
                    {limit: 10});
});
Run Code Online (Sandbox Code Playgroud)

//////////////////

尝试#2 - 穿过对象

客户

var oFilter = {
  Foo1: "bar"
}
Run Code Online (Sandbox Code Playgroud)

服务器

Meteor.publish("foos", function (oFilter) {
  return FooCl.find({oFilter}, 
                    {limit: 10});
});
Run Code Online (Sandbox Code Playgroud)

我目前没有机器,所以我无法提供有关抛出的错误类型的更多细节.希望今晚能有更多信息.谢谢你的帮助!

Dav*_*don 6

解决此问题的最简单方法是使用选择器进行订阅:

客户

var selector = {Foo1: {$in: aFoo1Filter}, Foo2: {$in: aFoo2Filter}};
Meteor.subscribe('foos', selector);
Run Code Online (Sandbox Code Playgroud)

服务器

Meteor.publish('foos', function (selector) {
  return FooCl.find(selector, {limit: 10});
});
Run Code Online (Sandbox Code Playgroud)

但是,重要的是要认识到这使客户能够从她想要的集合中请求任何文档FooCl.改进的解决方案是通过在选择器上使用匹配来限制可以请求的内容.例如:

Meteor.publish('foos', function(selector) {
  check(selector, {
    Foo1: Match.Optional({$in: [String]}),
    Foo2: Match.Optional({$in: [String]})
  });

  if (!_.isEmpty(selector)) {
    return FooCl.find(selector, {limit: 10});
  }
});
Run Code Online (Sandbox Code Playgroud)

这将确保selector在将任何文档发送到客户端之前符合可接受的模式.