我有身份验证日志表,我需要在该表上过滤掉特定的数据。不使用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 ...
它可以与上述解决方案一起使用,但是它又长又难看(我认为)。只是想知道是否有什么比我提供的更好?