Edgewall Software

Version 14 (modified by anonymous, 16 years ago) ( diff )

Changed the URL to Postgres Full Text Search. Part of pgsql 8.3

Advanced Search

One of the expected feature for 1.0 is a much improved search system.

But what exactly should be improved? This is the place to discuss it and make proposals.

Note that there's currently no development branch dedicated to this topic, but when there will be one, this page can be used to discuss the corresponding implementation details.

As usual with Trac, the challenge is that we're not only searching Wiki pages, but other kind of Trac resources as well: tickets, changesets, etc. Therefore, the result shown should also be adapted to the kind of object retrieved (see e.g. #2859).

A related question is how the TracSearch and the TracQuery should interact, see Trac-Dev:333, #1329, #2644.

Weighting

Right now, the results are returned in reverse chronological order (i.e. most recent first). All matches are considered equal. It was suggested that we could use some simple weighting techniques to return the results in a more useful order. For example, if a term is found in a ticket summary, this could "weight" more than if found in a ticket comment. Likewise, the number of times the term is found for a given result could be taken into account, etc.

It should be possible to do a first version of this improvement independently of the rest, by modifying the return type of ISearch.get_search_results to return a list of SearchResult object (much like the ITimelineEventProvider change).

Indexing

It would probably be a good idea if objects were indexed as they are created/updated. This would obviously improve search performance greatly, and no longer effectively require a full retrieval of the entire DB. This could be optional I guess.

A generic search system would provide components with a means to index content, query the content in a standard way (ie. a decent query language) and refer to this content at a later date (eg. ticket hits would display the ticket in a useful way, with links to specific comments, etc.)

Alec's Stream of Consciousness

If indexing on creation/update we would need hooks for each resource in Trac (ala IWikiChangeListener) to update the indexer. The potential downside for this is that indexing on the fly could slow down Trac's responsiveness at the cost of faster search. This could be mitigated by running the indexer in a thread. I like this solution.

For indexing itself, there seems to be two solutions: use a generalised indexing engine (Hyperestraier, Lucene, etc.) or in-database indexers. A generalised indexing engine has advantages in that one interface could be used for all resources (wiki, ticket, source, attachment, …). I am personally a fan of this option, and in particular pyndexter (bias!), which provides an abstraction layer for a number of indexers. It also includes a generic query language (similar to Google's) which is transformed into the query language particular to each backend.

So, here is a completely unthoughtout proposal:

# trac.wiki.search
from trac.search import SearchSystem

class WikiIndexer(Component):
    implements(IWikiChangeListener)

    def _update(self, page):
        SearchSystem(self.env).add('wiki:%s' % page.id, content=page.content)

    wiki_page_added = _update
    wiki_page_changed = _update
    wiki_page_version_deleted = _update

    def wiki_page_deleted(self, page):
        SearchSystem(self.env).remove('wiki:%s' % page.id)

This kind of system could be implemented entirely as a plugin, assuming appropriate ChangeListener style interfaces existed for all resources (currently only the versioncontrol module is missing this functionality).

Search Engines

Several search engines could be good candidate for handling the search requests, but probably this should be done in a pluggable way, so that different search engines could be supported.

Among the possible candidates:

Attachments (2)

Download all attachments as: .zip

Note: See TracWiki for help on using the wiki.