daevaorn / djapian

High level Xapian integration for Django
Other
6 stars 3 forks source link

Store Arbitrary data in search db #126

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
It would be really nice to be able to store non indexed data on the Indexer 
instances via tags and have that come back on the `Hit` object.

As it stands we are able to specify a tag, point it at a field or callable whos 
result will be indexed. 

The down side of the Hit objects is that we have to loop over them all and 
access the instance objects which requires a database query. This really 
defeats the purpose of a search index.

If there were a way to store information on the returning Hit object which 
mirrored how the indexer were defined via tags or some other attribute, a large 
work load could be taken off of the RDMS

Original issue reported on code.google.com by e3satter...@gmail.com on 28 Apr 2011 at 1:31

GoogleCodeExporter commented 9 years ago

Original comment by daevaorn on 28 Apr 2011 at 1:26

GoogleCodeExporter commented 9 years ago
If I understood you correct, we already have this feature.
Instances of the `Hit` class have `tags` field which is a dictionary with tags' 
values defined for Indexer. Is that what is you are talking about?

Original comment by esizi...@gmail.com on 3 Jun 2011 at 12:37

GoogleCodeExporter commented 9 years ago
Ah, yes, that maybe their intention, but I never get any information on the 
tags property of a hit object. 

They are always empty dictionaries. They are being index as I would expect and 
results are coming back I would expect. Hoever, tags never come back with 
anything

An indexer looks like this:

class GameSummaryIndexer(Indexer):
    fields = ['title','summary','body']
    tags = [
        ('title','title', 4),
        ('opponent', 'game_oppoment', 3),
        ('summary', 'summary', 2),
        ('body', 'as_plain_text', 1)
    ]

space.add_index(GameSummary, GameSummaryIndexer, attach_as='indexer')

here is how I am using It:

        if request.POST:
           # try:
            search = request.POST['searchVal']
            if " " in search:
                search = search.replace(" ", " OR ")
            if "." in search:
                search = search.replace(".", ' AND ')

            flags= xapian.QueryParser.FLAG_PARTIAL|xapian.QueryParser.FLAG_WILDCARD \
                |xapian.QueryParser.FLAG_BOOLEAN |xapian.QueryParser.FLAG_PHRASE

            indexers = [GameSummary.indexer, Article.indexer, Member.indexer, Team.indexer]
            comp = CompositeIndexer(*indexers)
            res = comp.search(search).flags(flags)

>>> for x in res:
       print x.tags, x.model

>>> {} <class 'hitmen.gamesummaries.models.GameSummary'>
>>> {} <class 'hitmen.gamesummaries.models.GameSummary'>
>>> {} <class 'hitmen.Stories.models.Article'>
>>> {} <class 'hitmen.gamesummaries.models.GameSummary'>
>>> {} <class 'hitmen.Stories.models.Article'>
>>> {} <class 'hitmen.gamesummaries.models.GameSummary'>
>>> {} <class 'hitmen.leaguemanager.models.Team'>
>>> {} <class 'hitmen.gamesummaries.models.GameSummary'>
>>> {} <class 'hitmen.gamesummaries.models.GameSummary'>
>>> {} <class 'hitmen.Stories.models.Article'>
>>> {} <class 'hitmen.gamesummaries.models.GameSummary'>

Original comment by e3satter...@gmail.com on 12 Jun 2011 at 7:26

GoogleCodeExporter commented 9 years ago
After doing a little digging this only seems to be the case when using a 
CompsiteIndexer.

If I work with the attached indexer directly from a model instance, The tags 
attribute is populated correctly. When I use a composite indexer, it is always 
empty.

Original comment by e3satter...@gmail.com on 12 Jun 2011 at 7:35