过滤特定数据的正确方法

时间:2019-01-23 08:56:45

标签: cassandra cql express-cassandra

我有身份验证日志表,我需要在该表上过滤掉特定的数据。不使用ALLOW FILTERING标志,创建cassandra表的最佳方法是什么?

因此,当前我的解决方案包括ALLOW FILTERING标志,我知道这对卡桑德拉来说是一个很大的问题。我目前正在尝试找出最好的情况。如果我只需要按一个键过滤条目,那很好,但是如果我必须按多个条目过滤,问题就会冒出来。所以说,我的表格结构如下-

Fields: ID, Username, Company, IP, Date
Key field: ID

最初,当我加载页面时,我想列出所有条目,因此,不添加任何过滤。在网站上,我有3种过滤条件-

Filter by: Username, Company, IP

在这种情况下,要么都不填,要么全部填满。

所以说我表中有以下数据

ID | Username | Company | IP          | Date
--------------------------------------------------
1  | test     | Comp1   | 192.111.0.1 | 20.01.2019
2  | test     | Comp1   | 192.112.1.1 | 21.01.2019
3  | user     | Comp3   | 192.112.1.1 | 21.01.2019

最初,当我加载页面时,我想返回所有条目。

如果将“公司过滤器”设置为Comp1,我只想返回ID为1和2的条目。

如果我要将用户名过滤器添加到test,我还要返回2个条目(1和2)。

如果我要将IP过滤器添加到192.112.1.1,我想返回ID为2的条目。

我可以使用ALLOW FILTERING来实现这一点,但是如果尝试创建实例化视图,则必须创建多个视图(1个用于公司返回,1个用于公司返回,1个用于IP地址返回,1个用于返回) (按公司和IP地址),1用于按公司和用户名返回,1用于按用户名和IP地址返回,最后1用于按用户名,公司和IP地址返回)。

然后在后端代码中,我将检查通过了哪种类型的过滤器,并在这种情况下使用根据实例化的视图。

P.S。该代码是用Express.JS编写的,而我使用的是express-cassandra

这是表格的模型(为了节省空间,我已经排除了所有实例化视图)

module.exports = {
  fields: {
    id: "uuid",
    user: "varchar",
    company: "varchar",
    ip: "varchar",
    date: {
      type: "timestamp",
      default: {"$db_function": "toTimestamp(now())"}
    }
  },
  key: [["id"], "user", "company", "date"],
  materialized_views: {
    auth_logs_by_all: {
      select: ["*"],
      key: [["user", "company", "ip"], "id", "date"],
      clustering_order: { "date": "desc" }
    },
    ...
  },
  index: [],
  custom_indexes: [],
  clustering_order: { "date": "desc" }
}

在我的控制器中,我会做这样的事情

let companyFilterUsed = false;
let userFilterUsed = false;
let ipFilterUsed = false;
let materialized_view;
if (req.body.company) {
  companyFilterUsed = true;
  options.company = req.body.company;
}

if (req.body.user) {
  userFilterUsed = true;
  options.user = req.body.user;
}

if (req.body.ip) {
  ipFilterUsed = true;
  options.ip = req.body.ip;
}

if (companyFilterUsed) {
  materialized_view = 'auth_logs_by_company';
}

if (userFilterUsed) {
  materialized_view = 'auth_logs_by_user';
}

if (ipFilterUsed) {
  materialized_view = 'auth_logs_by_ip';
}

if (companyFilterUsed && userFilterUsed) {
  materialized_view = 'auth_logs_by_user_and_company';
}

if (companyFilterUsed && ipFilterUsed) {
  materialized_view = 'auth_logs_by_ip_and_company';
}

if (userFilterUsed && ipFilterUsed) {
  materialized_view = 'auth_logs_by_ip_and_user';
}

if (userFilterUsed && ipFilterUsed && companyFilterUsed) {
  materialized_view = 'auth_logs_by_all';
}

... Afterwards accordingly pass in the materialized view to the query ...

它可以与上述解决方案一起使用,但是它又长又难看(我认为)。只是想知道是否有什么比我提供的更好?

0 个答案:

没有答案