【问题标题】:loopback REST API filter by nested data按嵌套数据环回 REST API 过滤器
【发布时间】:2019-04-28 22:22:27
【问题描述】:

我想通过嵌套数据从 REST API 中过滤。例如这个对象:

[
  {
    "name": "Handmade Soft Fish",
    "tags": "Rubber, Rubber, Salad",
    "categories": [
      {
        "name": "women",
        "id": 2,
        "parent_id": 0,
        "permalink": "/women"
      },
      {
        "name": "kids",
        "id": 3,
        "parent_id": 0,
        "permalink": "/kids"
      }
    ]
  },
  {
    "name": "Tasty Rubber Soap",
    "tags": "Granite, Granite, Chair",
    "categories": [
      {
        "name": "kids",
        "id": 3,
        "parent_id": 0,
        "permalink": "/kids"
      }
    ]
  }
]

正在通过 GET /api/products?filter[include]=categories 我只想获得类别名称为“女性”的产品。这是怎么做到的?

【问题讨论】:

    标签: filter loopbackjs loopback


    【解决方案1】:

    LoopBack 不支持基于相关模型的过滤器。

    不幸的是,这是我们从未有过带宽来解决的限制:(

    有关更多详细信息,请参阅此处的讨论和链接问题:

    【讨论】:

    • 这么多年还是没有带宽?
    【解决方案2】:

    也许您想通过Category REST API 获取这些数据。例如:

    GET /api/categories?filter[include]=products&filter[where][name]=woman

    结果将是一个带有所有products 相关的category 对象。为此,有必要在模型上声明这种关系。

    【讨论】:

    • 这是个好主意,但每个产品对象也有其他联系,例如变体、选项、图像等。然后我无法扩展产品的属性
    【解决方案3】:
    Try like this.It has worked for me.
    
      const filter = {
              where: {
                'categories.name': {
                  inq: ['women']**strong text**
                }
              }
            };
    
    Pass this filter to request as path parameters and the request would be like bellow
    
    GET /api/categoriesfilter=%7B%22where%22:%7B%categories.name%22:%7B%22inq%22:%5B%women%22%5D%7D%7D%7D
    

    【讨论】:

    • 这真的有效!我在本应有效的事情上挣扎了一个多小时,但这是解决问题的事情。
    【解决方案4】:

    你能分享一下没有 filter[include]=categorie 的样子吗?

    [编辑] 在评论几个问题后,我会构建一个远程方法:在common/models/myModel.js(函数内部):

    function getItems(filter, categorieIds = []) {
        return new Promise((resolve, reject) => {
            let newInclude;
            if (filter.hasOwnProperty(include)){
                if (Array.isArray(filter.include)) {
                    newInclude = [].concat(filter.include, "categories")
                }else{
                    if (filter.include.length > 0) {
                        newInclude = [].concat(filter.include, "categories");
                    }else{
                        newInclude = "categories";
                    }
                }
            }else{
                newInclude = "categories";
            }
    
            myModel.find(Object.assign({}, filter, {include: newInclude}))
            .then(data => {
                if (data.length <= 0) return resolve(data);
                if (categoriesIds.length <= 0) return resolve(data);
    
                // there goes your specific filter on categories
                const tmp = data.filter(
                    item => item.categories.findIndex(
                        categorie => categorieIds.indexOf(categorie.id) > -1
                    ) > -1
                );
                return resolve(tmp);
            })
        }
    }
    myModel.remoteMethod('getItems', {
        accepts: [{
            arg: "filter",
            type: "object",
            required: true
        }, {
            arg: "categorieIds",
            type: "array",
            required: true
        }],
        returns: {arg: 'getItems', type: 'array'}
    });
    

    希望它能回答你的问题...

    【讨论】:

    • [{ "name": "Handmade Soft Fish", "tags": "Rubber, Rubber, Salad" }, { "name": "Tasty Rubber Soap", "tags": "Granite, Granite, Chair" }] 看起来像这样
    • 为什么需要这样做?是出于只读目的还是您需要构建那种过滤器来创建/更新/删除? (对不起我的英语......)
    • 那么 filter[fields][name]=true&filter[fields][tags]=true&filter[fields][categorieId]=true 呢? (请用关系属性的名称替换categorieId)
    • 我需要类别页面上的此信息来仅显示给定类别的产品。然而,“类别”只是一个例子,因为在每个对象中我都有更多的属性也有嵌套数据,在其他情况下我可能会需要它
    • 它将适用于类别,以及在类似情况下,当键不同时,其他嵌套或在不同模型上工作。应该有一些通用的东西,但谢谢你的帮助
    猜你喜欢
    • 2019-06-13
    • 1970-01-01
    • 1970-01-01
    • 2018-05-17
    • 1970-01-01
    • 2021-06-21
    • 2018-05-13
    • 2021-01-17
    • 2020-07-22
    相关资源
    最近更新 更多