Question

I've got the following Restaurant and Comment models. I'm doing full text search on some fields of the Restaurant model, as shown below in the RestaurantIndexer class. How can I do a full text search including the comments (i.e. a search returning Restaurant instances with the query contained in one or some fields defined in RestaurantIndexer or in the comment field of Comment instances)?

*********Restaurant model***************

class Restaurant(models.Model):

    name = models.CharField(max_length=100)
    country=models.ForeignKey(Country)
    city=models.ForeignKey(City)
    street=models.CharField(max_length=100)
    street_number=models.PositiveSmallIntegerField()
    postal_code=models.PositiveIntegerField(blank=True,null=True)
    category=models.ManyToManyField(Category, blank=True,ull=True)
    slug = models.SlugField(unique=True)

*********Comment model***************

class Comment(models.Model):

    user = models.ForeignKey(User)
    restaurant = models.ForeignKey(Restaurant)
    submit_date = models.DateTimeField(blank = True, null = False)
    comment = models.TextField()

*********Restaurant indexer***************

class RestaurantIndexer(Indexer):
    tags = [
        ('name','name'),
        ('city','city'),
        ('country','country'),
        ('category', 'category'),
        ('tag','tag')
    ]

#how can I add Comment.comment?

space.add_index(Restaurant, RestaurantIndexer, attach_as='indexer') 
Was it helpful?

Solution

Djapian supports a dot notation to resolve fields and the path parts of tags in Indexer declarations. It also supports callables and using their result.

However, you don't need any of that since you just need to get all comments for a restaurant, you may simply do:

class RestaurantIndexer(Indexer):
    tags = [
        ('name','name'),
        ('city','city'),
        ('country','country.name'),
        ('category', 'category'),
        ('tag','tag'),
        ('comments', 'all_comments_text'),
    ]

class Restaurant(models.Model):
    # ... fields

    @property # could also be a method, since callables work
    def all_comments_text(self):
        return " ".join(map(lambda x: x.comment, self.comment_set.all()))

Note that this simply joins all comment fields on all related comment objects with a space. Should do for indexing, though.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top