feat(assist): full search

feat(api): live sessions full search
This commit is contained in:
Taha Yassine Kraiem 2022-06-15 21:56:59 +02:00
parent 2dbdfade10
commit c6b719b9fa
7 changed files with 84 additions and 40 deletions

View file

@ -34,7 +34,10 @@ def get_live_sessions_ws(project_id, body: schemas.LiveSessionsSearchPayloadSche
"sort": {"key": body.sort, "order": body.order}
}
for f in body.filters:
data["filter"][f.type] = f.value
if f.type == schemas.LiveFilterType.metadata:
data["filter"][f.source] = f.value
else:
data["filter"][f.type.value] = f.value
return __get_live_sessions_ws(project_id=project_id, data=data)

View file

@ -1018,25 +1018,32 @@ class LiveFilterType(str, Enum):
user_id = FilterType.user_id.value
user_anonymous_id = FilterType.user_anonymous_id.value
rev_id = FilterType.rev_id.value
page_title = "pageTitle"
#
# platform = "PLATFORM"
# metadata = "METADATA"
# issue = "ISSUE"
# events_count = "EVENTS_COUNT"
# utm_source = "UTM_SOURCE"
# utm_medium = "UTM_MEDIUM"
# utm_campaign = "UTM_CAMPAIGN"
page_title = "PAGETITLE"
session_id = "SESSIONID"
metadata = "METADATA"
user_UUID = "USERUUID"
tracker_version = "TRACKERVERSION"
user_browser_version = "USERBROWSERVERSION"
user_device_type = "USERDEVICETYPE",
timestamp = "TIMESTAMP"
class LiveSessionSearchFilterSchema(BaseModel):
value: Union[List[str], str] = Field(...)
type: LiveFilterType = Field(...)
source: Optional[str] = Field(None)
@root_validator
def validator(cls, values):
if values.get("type") is not None and values["type"] == LiveFilterType.metadata.value:
assert values.get("source") is not None, "source should not be null for METADATA type"
assert len(values.get("source")) > 0, "source should not be empty for METADATA type"
return values
class LiveSessionsSearchPayloadSchema(_PaginatedSchema):
filters: List[LiveSessionSearchFilterSchema] = Field([])
sort: str = Field(default="timestamp")
sort: LiveFilterType = Field(default=LiveFilterType.timestamp)
order: SortOrderType = Field(default=SortOrderType.desc)
@root_validator(pre=True)

View file

@ -93,7 +93,7 @@ const socketsList = async function (req, res) {
const connected_sockets = await io.in(peerId).fetchSockets();
for (let item of connected_sockets) {
if (item.handshake.query.identity === IDENTITIES.session && item.handshake.query.sessionInfo
&& isValidSession(item.handshake.query.sessionInfo, filters)) {
&& isValidSession(item.handshake.query.sessionInfo, filters.filter)) {
liveSessions[projectKey].push(sessionId);
}
}
@ -122,7 +122,7 @@ const socketsListByProject = async function (req, res) {
const connected_sockets = await io.in(peerId).fetchSockets();
for (let item of connected_sockets) {
if (item.handshake.query.identity === IDENTITIES.session && item.handshake.query.sessionInfo
&& isValidSession(item.handshake.query.sessionInfo, filters)) {
&& isValidSession(item.handshake.query.sessionInfo, filters.filter)) {
liveSessions[projectKey].push(sessionId);
}
}
@ -150,7 +150,7 @@ const socketsLive = async function (req, res) {
if (item.handshake.query.identity === IDENTITIES.session) {
liveSessions[projectKey] = liveSessions[projectKey] || [];
if (hasFilters(filters)) {
if (item.handshake.query.sessionInfo && isValidSession(item.handshake.query.sessionInfo, filters)) {
if (item.handshake.query.sessionInfo && isValidSession(item.handshake.query.sessionInfo, filters.filter)) {
liveSessions[projectKey].push(item.handshake.query.sessionInfo);
}
} else {
@ -181,7 +181,7 @@ const socketsLiveByProject = async function (req, res) {
if (item.handshake.query.identity === IDENTITIES.session) {
liveSessions[projectKey] = liveSessions[projectKey] || [];
if (hasFilters(filters)) {
if (item.handshake.query.sessionInfo && isValidSession(item.handshake.query.sessionInfo, filters)) {
if (item.handshake.query.sessionInfo && isValidSession(item.handshake.query.sessionInfo, filters.filter)) {
liveSessions[projectKey].push(item.handshake.query.sessionInfo);
}
} else {

View file

@ -75,7 +75,7 @@ const socketsList = async function (req, res) {
const connected_sockets = await io.in(peerId).fetchSockets();
for (let item of connected_sockets) {
if (item.handshake.query.identity === IDENTITIES.session && item.handshake.query.sessionInfo
&& isValidSession(item.handshake.query.sessionInfo, filters)) {
&& isValidSession(item.handshake.query.sessionInfo, filters.filter)) {
liveSessions[projectKey].push(sessionId);
}
}
@ -104,7 +104,7 @@ const socketsListByProject = async function (req, res) {
const connected_sockets = await io.in(peerId).fetchSockets();
for (let item of connected_sockets) {
if (item.handshake.query.identity === IDENTITIES.session && item.handshake.query.sessionInfo
&& isValidSession(item.handshake.query.sessionInfo, filters)) {
&& isValidSession(item.handshake.query.sessionInfo, filters.filter)) {
liveSessions[projectKey].push(sessionId);
}
}
@ -132,7 +132,7 @@ const socketsLive = async function (req, res) {
if (item.handshake.query.identity === IDENTITIES.session) {
liveSessions[projectKey] = liveSessions[projectKey] || [];
if (hasFilters(filters)) {
if (item.handshake.query.sessionInfo && isValidSession(item.handshake.query.sessionInfo, filters)) {
if (item.handshake.query.sessionInfo && isValidSession(item.handshake.query.sessionInfo, filters.filter)) {
liveSessions[projectKey].push(item.handshake.query.sessionInfo);
}
} else {
@ -162,7 +162,7 @@ const socketsLiveByProject = async function (req, res) {
if (item.handshake.query.identity === IDENTITIES.session) {
liveSessions[projectKey] = liveSessions[projectKey] || [];
if (hasFilters(filters)) {
if (item.handshake.query.sessionInfo && isValidSession(item.handshake.query.sessionInfo, filters)) {
if (item.handshake.query.sessionInfo && isValidSession(item.handshake.query.sessionInfo, filters.filter)) {
liveSessions[projectKey].push(item.handshake.query.sessionInfo);
}
} else {

View file

@ -1,4 +1,5 @@
const helper = require('./helper');
let debug = process.env.debug === "1" || false;
const getBodyFromUWSResponse = async function (res) {
return new Promise(((resolve, reject) => {
let buffer;
@ -51,21 +52,42 @@ const extractSessionIdFromRequest = function (req) {
return undefined;
}
const extractPayloadFromRequest = async function (req, res) {
let filters = {};
let filters = {
"query": {},
"filter": {}
};
if (process.env.uws === "true") {
if (req.getQuery("q")) {
debug && console.log(`[WS]where q=${req.getQuery("q")}`);
filters.query.value = [req.getQuery("q")];
}
if (req.getQuery("key")) {
debug && console.log(`[WS]where key=${req.getQuery("key")}`);
filters.query.key = [req.getQuery("key")];
}
if (req.getQuery("userId")) {
debug && console.log(`[WS]where userId=${req.getQuery("userId")}`);
filters.userID = [req.getQuery("userId")];
}
let body = await getBodyFromUWSResponse(res);
filters = {...filters, ...(body.filter || {})};
filters = {
...filters,
"sort": {
"key": body.sort && body.sort.key ? body.sort.key : undefined,
"order": body.sort && body.sort.order === "DESC"
},
"pagination": {
"limit": body.pagination && body.pagination.limit ? body.pagination.limit : undefined,
"page": body.pagination && body.pagination.page ? body.pagination.page : undefined
}
}
filters.filter = {...filters.filter, ...(body.filter || {})};
} else {
return helper.extractFiltersFromRequest(req);
return helper.extractPayloadFromRequest(req);
}
filters = helper.objectToObjectOfArrays({...filters, ...(req.body.filter || {})});
debug && console.log("payload/filters:")
debug && console.log(JSON.stringify(filters))
filters.filter = helper.objectToObjectOfArrays(filters.filter);
debug && console.log("payload/filters:" + JSON.stringify(filters))
return Object.keys(filters).length > 0 ? filters : undefined;
}
module.exports = {

View file

@ -89,7 +89,7 @@ const socketsListByProject = async function (req, res) {
const connected_sockets = await io.in(peerId).fetchSockets();
for (let item of connected_sockets) {
if (item.handshake.query.identity === IDENTITIES.session && item.handshake.query.sessionInfo
&& isValidSession(item.handshake.query.sessionInfo, filters)) {
&& isValidSession(item.handshake.query.sessionInfo, filters.filter)) {
liveSessions[projectKey].push(sessionId);
}
}
@ -117,7 +117,7 @@ const socketsLive = async function (req, res) {
if (item.handshake.query.identity === IDENTITIES.session) {
liveSessions[projectKey] = liveSessions[projectKey] || [];
if (hasFilters(filters)) {
if (item.handshake.query.sessionInfo && isValidSession(item.handshake.query.sessionInfo, filters)) {
if (item.handshake.query.sessionInfo && isValidSession(item.handshake.query.sessionInfo, filters.filter)) {
liveSessions[projectKey].push(item.handshake.query.sessionInfo);
}
} else {
@ -146,7 +146,7 @@ const socketsLiveByProject = async function (req, res) {
if (item.handshake.query.identity === IDENTITIES.session) {
liveSessions[projectKey] = liveSessions[projectKey] || [];
if (hasFilters(filters)) {
if (item.handshake.query.sessionInfo && isValidSession(item.handshake.query.sessionInfo, filters)) {
if (item.handshake.query.sessionInfo && isValidSession(item.handshake.query.sessionInfo, filters.filter)) {
liveSessions[projectKey].push(item.handshake.query.sessionInfo);
}
} else {

View file

@ -44,8 +44,8 @@ const isValidSession = function (sessionInfo, filters) {
let found = false;
for (const [skey, svalue] of Object.entries(sessionInfo)) {
if (svalue !== undefined && svalue !== null) {
if (svalue.constructor === Object) {
if (isValidSession(svalue, {key: values})) {
if (typeof (svalue) === "object") {
if (isValidSession(svalue, {[key]: values})) {
found = true;
break;
}
@ -74,7 +74,7 @@ const getValidAttributes = function (sessionInfo, query) {
let deduplicate = [];
for (const [skey, svalue] of Object.entries(sessionInfo)) {
if (svalue !== undefined && svalue !== null) {
if (svalue.constructor === Object) {
if (typeof (svalue) === "object") {
matches = [...matches, ...getValidAttributes(svalue, query)]
} else if ((query.key === undefined || skey.toLowerCase() === query.key.toLowerCase())
&& svalue.toLowerCase().indexOf(query.value.toLowerCase()) >= 0
@ -110,8 +110,14 @@ const extractPayloadFromRequest = function (req) {
let filters = {
"query": {},
"filter": {},
"sort": {"key": undefined, "order": false},
"pagination": {"limit": undefined, "page": undefined}
"sort": {
"key": req.body.sort && req.body.sort.key ? req.body.sort.key : undefined,
"order": req.body.sort && req.body.sort.order === "DESC"
},
"pagination": {
"limit": req.body.pagination && req.body.pagination.limit ? req.body.pagination.limit : undefined,
"page": req.body.pagination && req.body.pagination.page ? req.body.pagination.page : undefined
}
};
if (req.query.q) {
debug && console.log(`[WS]where q=${req.query.q}`);
@ -125,17 +131,23 @@ const extractPayloadFromRequest = function (req) {
debug && console.log(`[WS]where userId=${req.query.userId}`);
filters.filter.userID = [req.query.userId];
}
filters.filters = objectToObjectOfArrays(filters.filter);
filters = {...filters, ...(req.body.filter || {})};
debug && console.log("payload/filters:")
debug && console.log(JSON.stringify(filters))
filters.filter = objectToObjectOfArrays(filters.filter);
filters.filter = {...filters.filter, ...(req.body.filter || {})};
debug && console.log("payload/filters:" + JSON.stringify(filters))
return filters;
}
const sortPaginate = function (list, filters) {
let skey = "timestamp";
if (list.length > 0 && filters.sort.key) {
for (let key of Object.keys(list[0])) {
if (key.toLowerCase() == filters.sort.key.toLowerCase()) {
skey = key;
break;
}
}
}
list.sort((a, b) => {
let aV = (a[filters.sort.key] || a["timestamp"]);
let bV = (b[filters.sort.key] || b["timestamp"]);
return aV > bV ? 1 : aV < bV ? -1 : 0;
return a[skey] > b[skey] ? 1 : a[skey] < b[skey] ? -1 : 0;
})
if (filters.sort.order) {