0

我正在使用 jsdata 为 Angular 1.5 Web 应用程序创建本地缓存。我用相应的关系对我的数据进行了建模,一切正常。我正在为查询而苦苦挣扎,我什至不确定这是否适用于 js-data:

假设我有一组带有 ID 和名称的标签

 [
  {
    "id": 1,
    "name": "Tag 1"
  },
  {
    "id": 2,
    "name": "Tag 2"
  }
  ,
  {
    "id": 3,
    "name": "Tag 3"
  }
]

以及一些已分配标签的帖子:

[   {
      "id": 1,
      "name": "Post with tags 1 and 2",
      "tags": [1, 2]
    },
    {
      "id": 2,
      "name": "Post with tags 2 and 3",
      "tags": [2,3]
    },
    {
      "id": 3,
      "name": "Post with tag 3",
      "tags": [3]
    }
]

然后我定义了一个标签和帖子数据存储,并在帖子上设置了一个 hasMany 关系:

relations: {
hasMany: {
  tag: {
    localField: 'embedded_tags',
    localKeys: 'tags'
  }
}

当我查询帖子时,我看到我的标签出现在 embedded_tags 中,这很好。我现在想将我的帖子过滤到一组特定的标签:假设,我只想查看带有标签 2 和 3 的帖子,即帖子 2。

显然这不起作用:

var resultISect = postDS.filter({
  where: {
    'tags': {
      'iSectNotEmpty': [1, 2]
    }
  }
})

这也不会(当然会引发重复的键警告):

var resultAnd = postDS.filter({
  where: {
    'tags': {
      'contains': 3,
      'contains': 2
    }
  }
})

在 MongoDB / Mongoose 中有一个关键字 $all 正是这样做的。有没有办法在 jsData 中进行这样的过滤,或者这是一个太多的数据库任务,应该在后端完成 - 我想避免,因为这或多或少是拥有本地缓存​​副本的全部意义, 正确的?

Plunkr:http ://plnkr.co/edit/M44V8js0BtZaK6Xq9CYt?p=preview

4

2 回答 2

0

我向 js-data 添加了一个“matchAll”函数_utils2.default。这暂时有效,也许它对某人有帮助。

在交集函数旁边添加这个函数:

// check if array contains all elements queried
function matchAll(arr, elements) {

    if (!arr || !elements) {
        return true;
    }

    for (var i = 0, length = elements.length; i < length; i++) {
        if (contains(arr, elements[i])) {
            continue;
        } else {
            return false;
        }
    }
    return true;
}

将此函数与其他函数一起公开:

exports.default = {
    ...
    guid: guid,
    intersection: intersection,
    matchAll: matchAll,
    isArray: isArray,
    isBlacklisted: isBlacklisted,
    ...
}

并使其对新关键字做出反应:

...
} else if (op === 'isectEmpty') {
    expr = !_utils2.default.intersection(val || [], term || []).length;
} else if (op === 'isectNotEmpty') {
    expr = _utils2.default.intersection(val || [], term || []).length;
} else if (op === 'matchAll') {
    expr = _utils2.default.matchAll(val || [], term || []);
} else if (op === 'in') {
...
于 2017-05-19T15:09:51.267 回答
0

'where' 可以是一个数组,这应该有效:

where: [
  {
    tags: {
      contains: 3
    }
  },
  'and'
  {
    tags: {
      contains: 2
    }
  }
]

取自这里:https ://github.com/js-data/js-data/blob/c3fcde1abab910cdf4d39e3fbc42699a3b27c1da/test/unit/query/filter.test.js#L243 (发现所有过滤器功能的好地方,顺便说一句)

于 2017-05-29T15:14:28.500 回答