У меня есть таблица журнала аутентификации, по которой мне нужно будет отфильтровать определенные данные.Что было бы лучшим способом создать таблицу cassandra, чтобы не использовать флаг ALLOW FILTERING
?
Итак, в настоящее время мое решение включает флаг 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
Изначально, когда я загружал страницу, я хотел бы вернуть все записи.
Если бы для Filter for Company было установлено значение Comp1
, я хотел бы возвращать только записи сИдентификаторы 1 и 2.
Если бы я добавил фильтр имени пользователя к test
, я хотел бы также вернуть 2 записи (1 и 2).
Если бы я добавил фильтр IP к 192.112.1.1
, я хотел бы вернуть запись с идентификатором 2.
Я могу добиться этого с помощью ALLOW FILTERING, но если я попытаюсь создать материализованное представление, мне придется создать несколько из них (1 для возврата компанией1 для возвращающейся компании, 1 для возврата по IP-адресу, 1 для возврата по компании и IP-адресу, 1 для возврата по компании и имени пользователя, 1 для возврата по имени пользователя и IP-адресу и, наконец, 1 для возврата по имени пользователя, компании и IP-адресу).
А в бэкэнд-коде я бы проверил, какие типы фильтров пропущены, и в этом случае использовал бы материализованное представление.
PS Код написан на 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 ...
Это будет работать с вышеупомянутым решением, но это долго и некрасиво (по моему мнению).Просто интересно, есть ли что-нибудь лучше, чем мой при условии?