当子级别为空时,从Loopback find()中排除第一级过滤器中的项目

时间:2022-10-03 23:45:20

When using Strongloop Loopback, we can make a data request (with relations) to the database these ways:

使用Strongloop Loopback时,我们可以通过以下方式向数据库发出数据请求(带关系):

(1) Using lb-service (at front-end)

(1)使用lb-service(在前端)

Model.find({
  filter: {
    where: {id: 1},
    include: {
      relation: 'relationship',
      scope: {where: {id: 2}}
    }
  }
}, function (instances) {
}, function (err) {
});

(2) Using node.js (at server-side)

(2)使用node.js(在服务器端)

Model.find({
  where: {id: 1},
  include: {
    relation: 'relationship',
    scope: {where: {id: 2}}
  }
}, function (err, instances) {
});

What I need: Exclude items from first filter whether another filter fails. There is one obvious solution: filtering the response, this way:

我需要:从第一个过滤器中排除项目是否有另一个过滤器失败。有一个明显的解决方案:过滤响应,这样:

instances = instances.filter(function(instance){
  return typeof(instance.relationship) !== "undefined";
});

But... Using filter() to eliminate is not a good scalable solution, because it will always iterate over the array. Using this solution at the front-end is not good, because the size of the array will slow down the performance. Bringing it to the server-side could be a solution. But... each model will have a particular set of relations... and it is not scalable again!

但是......使用filter()消除不是一个很好的可扩展解决方案,因为它总是遍历数组。在前端使用此解决方案并不好,因为阵列的大小会降低性能。将它带到服务器端可能是一个解决方案。但是......每个模型都会有一组特定的关系......而且它不再可扩展!

Main question: Is there some way to overcome this situation, excluding items from the first filter whether second (third, or more) fails simultaneously (or not)?

主要问题:是否有某种方法可以克服这种情况,从第一个过滤器中排除项目是否第二个(第三个或更多)同时失败(或不同步)?

Something like, defining it on filter object:

类似的东西,在过滤器对象上定义它:

var filter = {
  where: {id: 1},
  include: {
    relation: {name: 'relationship', required: true}, // required means this filter *needs* to be satisfied 
    scope: {where: {id: 2}}
  }
};

Requirements:

要求:

(1) SQL query is not an option ;)

(1)SQL查询不是一个选项;)

(2) I am using MySQL as database. So things like

(2)我使用MySQL作为数据库。所以像

{ where: { id: 1, relationship.id: 2 } }

{where:{id:1,relationship.id:2}}

will not work as desired.

不会按预期工作。

1 个解决方案

#1


0  

I don't know of a way to do this within the filter syntax itself. I think you would have to write a custom remote method to do the filtering yourself after the initial query was complete. Here's what that might look like:

我不知道在过滤器语法本身中如何做到这一点。我认为你必须编写一个自定义远程方法,在初始查询完成后自己进行过滤。这可能是这样的:

// in /common/models/model.js

Model.filterResults = function filterResults(filter, next) {
  Model.find(filter, function doFilter(err, data) {
    if (err) { return next(err); }

    var filteredData = data.filter(function(model) {
      return model.otherThings && model.otherThings().length;
    });

    next(null, filteredData);
  });
};

Model.remoteMethod(
  'filterResults',
  {
    accepts: { arg: 'filter', type: 'object', http: { source: 'query' } },
    returns: { arg: 'results', type: 'array' },
    http: { verb: 'get', path: '/no-empties' }
  }
);

Now you can hit: .../api/Models/no-empies?filter={"include":"otherThings"} and you will only get back Models that have a related OtherThing. Note that this is for a one-to-many relationship, but hopefully you can see how to change it to fit your needs.

现在您可以点击:... / api / Models / no-empies?filter = {“include”:“otherThings”}并且您只会返回具有相关OtherThing的模型。请注意,这是一对多关系,但希望您可以看到如何更改它以满足您的需求。

#1


0  

I don't know of a way to do this within the filter syntax itself. I think you would have to write a custom remote method to do the filtering yourself after the initial query was complete. Here's what that might look like:

我不知道在过滤器语法本身中如何做到这一点。我认为你必须编写一个自定义远程方法,在初始查询完成后自己进行过滤。这可能是这样的:

// in /common/models/model.js

Model.filterResults = function filterResults(filter, next) {
  Model.find(filter, function doFilter(err, data) {
    if (err) { return next(err); }

    var filteredData = data.filter(function(model) {
      return model.otherThings && model.otherThings().length;
    });

    next(null, filteredData);
  });
};

Model.remoteMethod(
  'filterResults',
  {
    accepts: { arg: 'filter', type: 'object', http: { source: 'query' } },
    returns: { arg: 'results', type: 'array' },
    http: { verb: 'get', path: '/no-empties' }
  }
);

Now you can hit: .../api/Models/no-empies?filter={"include":"otherThings"} and you will only get back Models that have a related OtherThing. Note that this is for a one-to-many relationship, but hopefully you can see how to change it to fit your needs.

现在您可以点击:... / api / Models / no-empies?filter = {“include”:“otherThings”}并且您只会返回具有相关OtherThing的模型。请注意,这是一对多关系,但希望您可以看到如何更改它以满足您的需求。