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