synapse/storage/search.py
def search_msgs(self, room_ids, search_term, keys):
        """Performs a full text search over events with given keys.

        Args:
            room_ids (list): List of room ids to search in
            search_term (str): Search term to search for
            keys (list): List of keys to search in, currently supports
                "content.body", "content.name", "content.topic"

        Returns:
            list of dicts
        """
        clauses = []

        search_query = search_query = _parse_query(self.database_engine, search_term)

        args = []

        # Make sure we don't explode because the person is in too many rooms.
        # We filter the results below regardless.
        if len(room_ids) < 500:
            clauses.append(
                "room_id IN (%s)" % (",".join(["?"] * len(room_ids)),)
            )
            args.extend(room_ids)

        local_clauses = []
        for key in keys:
            local_clauses.append("key = ?")
            args.append(key)

        clauses.append(
            "(%s)" % (" OR ".join(local_clauses),)
        )

        count_args = args
        count_clauses = clauses

        if isinstance(self.database_engine, PostgresEngine):
            sql = (
                "SELECT ts_rank_cd(vector, to_tsquery('english', ?)) AS rank,"
                " room_id, event_id"
                " FROM event_search"
                " WHERE vector @@ to_tsquery('english', ?)"
            )
            args = [search_query, search_query] + args

            count_sql = (
                "SELECT room_id, count(*) as count FROM event_search"
                " WHERE vector @@ to_tsquery('english', ?)"
            )
            count_args = [search_query] + count_args
        elif isinstance(self.database_engine, Sqlite3Engine):
            sql = (
                "SELECT rank(matchinfo(event_search)) as rank, room_id, event_id"
                " FROM event_search"
                " WHERE value MATCH ?"
            )
            args = [search_query] + args

            count_sql = (
                "SELECT room_id, count(*) as count FROM event_search"
                " WHERE value MATCH ?"
            )
            count_args = [search_term] + count_args
        else:
            # This should be unreachable.
            raise Exception("Unrecognized database engine")

        for clause in clauses:
            sql += " AND " + clause

        for clause in count_clauses:
            count_sql += " AND " + clause

        # We add an arbitrary limit here to ensure we don't try to pull the
        # entire table from the database.
        sql += " ORDER BY rank DESC LIMIT 500"

        results = yield self._execute(
            "search_msgs", self.cursor_to_dict, sql, *args
        )

        results = filter(lambda row: row["room_id"] in room_ids, results)

        events = yield self._get_events([r["event_id"] for r in results])

        event_map = {
            ev.event_id: ev
            for ev in events
        }

        highlights = None
        if isinstance(self.database_engine, PostgresEngine):
            highlights = yield self._find_highlights_in_postgres(search_query, events)

        count_sql += " GROUP BY room_id"

        count_results = yield self._execute(
            "search_rooms_count", self.cursor_to_dict, count_sql, *count_args
        )

        count = sum(row["count"] for row in count_results if row["room_id"] in room_ids)

        defer.returnValue({
            "results": [
                {
                    "event": event_map[r["event_id"]],
                    "rank": r["rank"],
                }
                for r in results
                if r["event_id"] in event_map
            ],
            "highlights": highlights,
            "count": count,
        })
Performs a full text search over events with given keys.

        Args:
            room_ids (list): List of room ids to search in
            search_term (str): Search term to search for
            keys (list): List of keys to search in, currently supports
                "content.body", "content.name", "content.topic"

        Returns:
            list of dicts
        
Performs a full text search over events with given keys.
Performs a full text search over events with given keys .
def search_msgs(self, room_ids, search_term, keys):
        clauses = []
        search_query = search_query = _parse_query(self.database_engine, search_term)
        args = []
        if len(room_ids) < 500:
            clauses.append(
                "room_id IN (%s)" % (",".join(["?"] * len(room_ids)),)
            )
            args.extend(room_ids)
        local_clauses = []
        for key in keys:
            local_clauses.append("key = ?")
            args.append(key)
        clauses.append(
            "(%s)" % (" OR ".join(local_clauses),)
        )
        count_args = args
        count_clauses = clauses
        if isinstance(self.database_engine, PostgresEngine):
            sql = (
                "SELECT ts_rank_cd(vector, to_tsquery('english', ?)) AS rank,"
                " room_id, event_id"
                " FROM event_search"
                " WHERE vector @@ to_tsquery('english', ?)"
            )
            args = [search_query, search_query] + args
            count_sql = (
                "SELECT room_id, count(*) as count FROM event_search"
                " WHERE vector @@ to_tsquery('english', ?)"
            )
            count_args = [search_query] + count_args
        elif isinstance(self.database_engine, Sqlite3Engine):
            sql = (
                "SELECT rank(matchinfo(event_search)) as rank, room_id, event_id"
                " FROM event_search"
                " WHERE value MATCH ?"
            )
            args = [search_query] + args
            count_sql = (
                "SELECT room_id, count(*) as count FROM event_search"
                " WHERE value MATCH ?"
            )
            count_args = [search_term] + count_args
        else:
            raise Exception("Unrecognized database engine")
        for clause in clauses:
            sql += " AND " + clause
        for clause in count_clauses:
            count_sql += " AND " + clause
        sql += " ORDER BY rank DESC LIMIT 500"
        results = yield self._execute(
            "search_msgs", self.cursor_to_dict, sql, *args
        )
        results = filter(lambda row: row["room_id"] in room_ids, results)
        events = yield self._get_events([r["event_id"] for r in results])
        event_map = {
            ev.event_id: ev
            for ev in events
        }
        highlights = None
        if isinstance(self.database_engine, PostgresEngine):
            highlights = yield self._find_highlights_in_postgres(search_query, events)
        count_sql += " GROUP BY room_id"
        count_results = yield self._execute(
            "search_rooms_count", self.cursor_to_dict, count_sql, *count_args
        )
        count = sum(row["count"] for row in count_results if row["room_id"] in room_ids)
        defer.returnValue({
            "results": [
                {
                    "event": event_map[r["event_id"]],
                    "rank": r["rank"],
                }
                for r in results
                if r["event_id"] in event_map
            ],
            "highlights": highlights,
            "count": count,
        })
def search_msgs ( self , room_ids , search_term , keys ) : clauses = [ ] search_query = search_query = _parse_query ( self . database_engine , search_term ) args = [ ] if len ( room_ids ) < 500 : clauses . append ( "room_id IN (%s)" % ( "," . join ( [ "?" ] * len ( room_ids ) ) , ) ) args . extend ( room_ids ) local_clauses = [ ] for key in keys : local_clauses . append ( "key = ?" ) args . append ( key ) clauses . append ( "(%s)" % ( " OR " . join ( local_clauses ) , ) ) count_args = args count_clauses = clauses if isinstance ( self . database_engine , PostgresEngine ) : sql = ( "SELECT ts_rank_cd(vector, to_tsquery('english', ?)) AS rank," " room_id, event_id" " FROM event_search" " WHERE vector @@ to_tsquery('english', ?)" ) args = [ search_query , search_query ] + args count_sql = ( "SELECT room_id, count(*) as count FROM event_search" " WHERE vector @@ to_tsquery('english', ?)" ) count_args = [ search_query ] + count_args elif isinstance ( self . database_engine , Sqlite3Engine ) : sql = ( "SELECT rank(matchinfo(event_search)) as rank, room_id, event_id" " FROM event_search" " WHERE value MATCH ?" ) args = [ search_query ] + args count_sql = ( "SELECT room_id, count(*) as count FROM event_search" " WHERE value MATCH ?" ) count_args = [ search_term ] + count_args else : raise Exception ( "Unrecognized database engine" ) for clause in clauses : sql += " AND " + clause for clause in count_clauses : count_sql += " AND " + clause sql += " ORDER BY rank DESC LIMIT 500" results = yield self . _execute ( "search_msgs" , self . cursor_to_dict , sql , * args ) results = filter ( lambda row : row [ "room_id" ] in room_ids , results ) events = yield self . _get_events ( [ r [ "event_id" ] for r in results ] ) event_map = { ev . event_id : ev for ev in events } highlights = None if isinstance ( self . database_engine , PostgresEngine ) : highlights = yield self . _find_highlights_in_postgres ( search_query , events ) count_sql += " GROUP BY room_id" count_results = yield self . _execute ( "search_rooms_count" , self . cursor_to_dict , count_sql , * count_args ) count = sum ( row [ "count" ] for row in count_results if row [ "room_id" ] in room_ids ) defer . returnValue ( { "results" : [ { "event" : event_map [ r [ "event_id" ] ] , "rank" : r [ "rank" ] , } for r in results if r [ "event_id" ] in event_map ] , "highlights" : highlights , "count" : count , } )
Performs a full text search over events with given keys.
Performs a full text search over events with given keys .
"""Performs a full text search over events with given keys.

        Args:
            room_ids (list): List of room ids to search in
            search_term (str): Search term to search for
            keys (list): List of keys to search in, currently supports
                "content.body", "content.name", "content.topic"

        Returns:
            list of dicts
        """ # Make sure we don't explode because the person is in too many rooms. # We filter the results below regardless. # This should be unreachable. # We add an arbitrary limit here to ensure we don't try to pull the # entire table from the database.
list of dicts
list of dicts
self
room_ids
List of room ids to search in
List of room ids to search in
search_term
Search term to search for
Search term to search for
keys
List of keys to search in, currently supports
"content.body", "content.name", "content.topic"
List of keys to search in currently supports " content . body " " content . name " " content . topic "