diff --git a/database/Database.php b/database/Database.php index 6d0100f36237f904732d87c8c2db5790de5fb6e8..39fdb1975c51071cde29af41f2b0e71b46cac77b 100644 --- a/database/Database.php +++ b/database/Database.php @@ -77,7 +77,6 @@ class Database public function find(string $query, int $since = null, int $before = null, string $buffer = null, string $network = null, string $sender = null, int $limitPerBuffer = 4): array { $truncatedLimit = max(min($limitPerBuffer, 10), 0); - $truncatedLimit = 20; $messages = $this->findInBufferMultiple($query, $since, $before, $buffer, $network, $sender, $truncatedLimit); $hasMore = $this->findInBufferMultipleCount($query, $since, $before, $buffer, $network, $sender, 0, $truncatedLimit); diff --git a/database/backends/PostgresSmartBackend.php b/database/backends/PostgresSmartBackend.php index 0c32d2c18ae5cb788675834ea7511ed5692898a3..3030dce08ccfbdf52bccfe7588f5226e8f2813da 100644 --- a/database/backends/PostgresSmartBackend.php +++ b/database/backends/PostgresSmartBackend.php @@ -27,61 +27,64 @@ class PostgresSmartBackend implements Backend { return $this->db->prepare(" SELECT - tmp.bufferid, - tmp.buffername, + ranked_messages.bufferid, + ranked_messages.buffername, network.networkname, - tmp.messageid, + ranked_messages.messageid, + ranked_messages.time, sender.sender, - tmp.time, - ts_headline(replace(replace(tmp.message, '<', '<'), '>', '>'), query, 'HighlightAll=TRUE') AS message + ts_headline(replace(replace(ranked_messages.message, '<', '<'), '>', '>'), query, 'HighlightAll=TRUE') AS message FROM (SELECT - backlog.messageid, - backlog.bufferid, - buffer.buffername, - buffer.networkid, - backlog.senderid, - backlog.time, - backlog.message, - ( - (ts_rank(tsv, query, :config_normalization) ^ :weight_content) * - ((CASE - WHEN type IN (1, 4) THEN 1.0 - WHEN type IN (2, 1024, 2048, 4096, 16384) THEN 0.75 - WHEN type IN (32, 64, 128, 256, 512, 32768, 65536) THEN 0.5 - WHEN type IN (8, 16, 8192, 131072) THEN 0.25 - ELSE 0.1 END) ^ :weight_type) * - ((EXTRACT(EPOCH FROM time) / EXTRACT(EPOCH FROM CURRENT_TIMESTAMP)) ^ :weight_time) - ) AS rank_value, - rank() OVER ( - PARTITION BY backlog.bufferid - ORDER BY ( - (ts_rank(tsv, query, :config_normalization) ^ :weight_content) * - ((CASE - WHEN type IN (1, 4) THEN 1.0 - WHEN type IN (2, 1024, 2048, 4096, 16384) THEN 0.75 - WHEN type IN (32, 64, 128, 256, 512, 32768, 65536) THEN 0.5 - WHEN type IN (8, 16, 8192, 131072) THEN 0.25 - ELSE 0.1 END) ^ :weight_type) * - ((EXTRACT(EPOCH FROM time) / EXTRACT(EPOCH FROM CURRENT_TIMESTAMP)) ^ :weight_time) - ) DESC - ) AS rank, - query - FROM backlog - JOIN buffer ON backlog.bufferid = buffer.bufferid, - phraseto_tsquery_multilang(:query) query - WHERE buffer.userid = :userid - AND (:ignore_since::BOOLEAN OR backlog.time > :since::TIMESTAMP) - AND (:ignore_before::BOOLEAN OR backlog.time < :before::TIMESTAMP) - AND (:ignore_buffer::BOOLEAN OR buffer.buffername ~* :buffer) - AND backlog.tsv @@ query AND backlog.type & 23559 > 0 - ) tmp - JOIN sender ON tmp.senderid = sender.senderid - JOIN network ON tmp.networkid = network.networkid - WHERE tmp.rank <= :limit + matching_messages.*, + rank() + OVER ( + PARTITION BY matching_messages.bufferid + ORDER BY matching_messages.rank_value DESC + ) AS rank, + first_value(rank_value) + OVER ( + PARTITION BY matching_messages.bufferid + ORDER BY matching_messages.rank_value DESC + ) AS max_rank_value + FROM + (SELECT + backlog.messageid, + backlog.bufferid, + buffer.buffername, + buffer.networkid, + backlog.senderid, + backlog.time, + backlog.message, + query, + ( + (ts_rank(tsv, query, :config_normalization) ^ :weight_content) * + ((CASE + WHEN TYPE IN (1, 4) THEN 1.0 + WHEN TYPE IN (2, 1024, 2048, 4096, 16384) THEN 0.75 + WHEN TYPE IN (32, 64, 128, 256, 512, 32768, 65536) THEN 0.5 + WHEN TYPE IN (8, 16, 8192, 131072) THEN 0.25 + ELSE 0.1 END) ^ :weight_type) * + ((EXTRACT(EPOCH FROM TIME) / EXTRACT(EPOCH FROM CURRENT_TIMESTAMP)) ^ :weight_time) + ) AS rank_value + FROM + backlog + JOIN buffer ON backlog.bufferid = buffer.bufferid + , phraseto_tsquery_multilang(:query) query + WHERE buffer.userid = :userid + AND (:ignore_since::BOOLEAN OR backlog.time > :since::TIMESTAMP) + AND (:ignore_before::BOOLEAN OR backlog.time < :before::TIMESTAMP) + AND (:ignore_buffer::BOOLEAN OR buffer.buffername ~* :buffer) + AND backlog.type & 23559 > 0 + AND backlog.tsv @@ query + ) matching_messages + ) ranked_messages + JOIN sender ON ranked_messages.senderid = sender.senderid + JOIN network ON ranked_messages.networkid = network.networkid + WHERE ranked_messages.rank <= :limit AND (:ignore_network::BOOLEAN OR network.networkname ~* :network) AND (:ignore_sender::BOOLEAN OR sender.sender ~* :sender) - ORDER BY tmp.rank_value DESC; + ORDER BY ranked_messages.max_rank_value DESC, ranked_messages.rank_value DESC "); } @@ -91,11 +94,12 @@ class PostgresSmartBackend implements Backend SELECT backlog.bufferid, COUNT(backlog.messageid) > (:limit::INT + :offset::INT) AS hasmore - FROM backlog - JOIN buffer ON backlog.bufferid = buffer.bufferid - JOIN sender ON backlog.senderid = sender.senderid - JOIN network ON buffer.networkid = network.networkid, - phraseto_tsquery_multilang(:query) query + FROM + backlog + JOIN buffer ON backlog.bufferid = buffer.bufferid + JOIN sender ON backlog.senderid = sender.senderid + JOIN network ON buffer.networkid = network.networkid + , phraseto_tsquery_multilang(:query) query WHERE buffer.userid = :userid AND (:ignore_since::BOOLEAN OR backlog.time > :since::TIMESTAMP) AND (:ignore_before::BOOLEAN OR backlog.time < :before::TIMESTAMP) @@ -111,43 +115,52 @@ class PostgresSmartBackend implements Backend { return $this->db->prepare(" SELECT - tmp.bufferid, - tmp.messageid, + matching_messages.bufferid, + matching_messages.buffername, + network.networkname, + matching_messages.messageid, + matching_messages.time, sender.sender, - tmp.time, - ts_headline(replace(replace(tmp.message, '<', '<'), '>', '>'), query, 'HighlightAll=TRUE') AS message + ts_headline(replace(replace(matching_messages.message, '<', '<'), '>', '>'), query, 'HighlightAll=TRUE') AS message FROM (SELECT backlog.messageid, backlog.bufferid, + buffer.buffername, + buffer.networkid, backlog.senderid, backlog.time, backlog.message, + query, ( (ts_rank(tsv, query, :config_normalization) ^ :weight_content) * ((CASE - WHEN type IN (1, 4) THEN 1.0 - WHEN type IN (2, 1024, 2048, 4096, 16384) THEN 0.75 - WHEN type IN (32, 64, 128, 256, 512, 32768, 65536) THEN 0.5 - WHEN type IN (8, 16, 8192, 131072) THEN 0.25 + WHEN TYPE IN (1, 4) THEN 1.0 + WHEN TYPE IN (2, 1024, 2048, 4096, 16384) THEN 0.75 + WHEN TYPE IN (32, 64, 128, 256, 512, 32768, 65536) THEN 0.5 + WHEN TYPE IN (8, 16, 8192, 131072) THEN 0.25 ELSE 0.1 END) ^ :weight_type) * - ((EXTRACT(EPOCH FROM time) / EXTRACT(EPOCH FROM CURRENT_TIMESTAMP)) ^ :weight_time) - ) AS rank_value, - query - FROM backlog - JOIN buffer ON backlog.bufferid = buffer.bufferid, - phraseto_tsquery_multilang(:query) query + ((EXTRACT(EPOCH FROM TIME) / EXTRACT(EPOCH FROM CURRENT_TIMESTAMP)) ^ :weight_time) + ) AS rank_value + FROM + backlog + JOIN buffer ON backlog.bufferid = buffer.bufferid + , phraseto_tsquery_multilang(:query) query WHERE buffer.userid = :userid - AND backlog.bufferid = :bufferid + AND buffer.bufferid = :bufferid AND (:ignore_since::BOOLEAN OR backlog.time > :since::TIMESTAMP) AND (:ignore_before::BOOLEAN OR backlog.time < :before::TIMESTAMP) - AND backlog.tsv @@ query AND backlog.type & 23559 > 0 - ) tmp - JOIN sender ON tmp.senderid = sender.senderid - WHERE (:ignore_sender::BOOLEAN OR sender.sender ~* :sender) - ORDER BY tmp.rank_value DESC + AND (:ignore_buffer::BOOLEAN OR buffer.buffername ~* :buffer) + AND backlog.type & 23559 > 0 + AND backlog.tsv @@ query + ) matching_messages + JOIN sender ON matching_messages.senderid = sender.senderid + JOIN network ON matching_messages.networkid = network.networkid + WHERE (:ignore_network::BOOLEAN OR network.networkname ~* :network) + AND (:ignore_sender::BOOLEAN OR sender.sender ~* :sender) + ORDER BY matching_messages.rank_value DESC LIMIT :limit - OFFSET :offset; + OFFSET :offset "); } @@ -157,10 +170,11 @@ class PostgresSmartBackend implements Backend SELECT backlog.bufferid, COUNT(backlog.messageid) > (:limit::INT + :offset::INT) AS hasmore - FROM backlog - JOIN buffer ON backlog.bufferid = buffer.bufferid - JOIN sender ON backlog.senderid = sender.senderid, - phraseto_tsquery_multilang(:query) query + FROM + backlog + JOIN buffer ON backlog.bufferid = buffer.bufferid + JOIN sender ON backlog.senderid = sender.senderid + , phraseto_tsquery_multilang(:query) query WHERE buffer.userid = :userid AND backlog.bufferid = :bufferid AND (:ignore_since::BOOLEAN OR backlog.time > :since::TIMESTAMP) @@ -181,10 +195,11 @@ class PostgresSmartBackend implements Backend backlog.time, network.networkname, replace(replace(replace(backlog.message, '&', '&'), '<', '<'), '>', '>') AS message - FROM backlog - JOIN sender ON backlog.senderid = sender.senderid - JOIN buffer ON backlog.bufferid = buffer.bufferid - JOIN network ON buffer.networkid = network.networkid + FROM + backlog + JOIN sender ON backlog.senderid = sender.senderid + JOIN buffer ON backlog.bufferid = buffer.bufferid + JOIN network ON buffer.networkid = network.networkid WHERE buffer.userid = :userid AND backlog.bufferid = :bufferid AND backlog.messageid >= :anchor @@ -203,10 +218,11 @@ class PostgresSmartBackend implements Backend backlog.time, network.networkname, replace(replace(replace(backlog.message, '&', '&'), '<', '<'), '>', '>') AS message - FROM backlog - JOIN sender ON backlog.senderid = sender.senderid - JOIN buffer ON backlog.bufferid = buffer.bufferid - JOIN network ON buffer.networkid = network.networkid + FROM + backlog + JOIN sender ON backlog.senderid = sender.senderid + JOIN buffer ON backlog.bufferid = buffer.bufferid + JOIN network ON buffer.networkid = network.networkid WHERE buffer.userid = :userid AND backlog.bufferid = :bufferid AND backlog.messageid < :anchor diff --git a/res/js/app.js b/res/js/app.js index 496edfe387c1603737d05170f07d2de7848fd265..9d4a412058648680bdcb232acf219325c94cc386 100644 --- a/res/js/app.js +++ b/res/js/app.js @@ -39,7 +39,7 @@ class App { this.loadingQuery++; const queryId = this.loadingQuery; load("web/search/", {query: query}).then((result) => { - if (this.loadingQuery != queryId) + if (this.loadingQuery !== queryId) return; this.buffers = result.map((buffer) => { diff --git a/res/js/util/statehandler.js b/res/js/util/statehandler.js index bc1c3cec04c4eae983622dab620d1447fc9414de..38dd687ef90adef0b1b697952650ffc179c97b76 100644 --- a/res/js/util/statehandler.js +++ b/res/js/util/statehandler.js @@ -24,7 +24,7 @@ class StateHandler extends Component { const oldState = this.state; this.state = decodeURIComponent(window.location.hash.substr(1)); - if (this.state !== oldState && this.state !== "") + if (this.state !== oldState && this.state.length > 0) this.sendEvent("update", [this.state]); }