Thomas Wanschik on March 29, 2010

Nonrel-search released

Update 2: Post outdated. See the documentation or reference for usage info. Basically you should index your models in a separate file "<app_name>.search_indexes" using the function search.register . This keeps the indexes independent of your models and you don't have to modify your models anymore to make them searchable.

Update: SearchIndexField has been removed. In order to index and search your data you have to add a SearchManager to your model definition which takes the same arguments as SearchIndexField before.

We are happy to release our first port of gae-search to django-nonrel :) Nonrel-search is a simple full text search engine for nonrelational databases like App Engine using native Django. This is especially useful for users of gae-search which want to switch to django-nonrel. So let's see how to use nonrel-search.

Indexing and searching your data

In nonrel-search you can make your entities searchable by indexing them. You do so by adding a SearchManager to your model definition:

from django.db import models from search.core import SearchManager, porter_stemmer class Post(models.Model): title = models.CharField(max_length=500) content = models.TextField() author = models.CharField(max_length=500) category = models.CharField(max_length=500) rating = models.IntegerField(choices=[(0, 'zero'), (1, 'one'), (2, 'two'), (3, 'three'), (4, 'four'), (5, 'five'), ], default=0) # index used to retrieve posts via the title, content or the # category. search_index = SearchManager(('title', 'content', 'category'), indexer=porter_stemmer)

As you can see, you can make posts searchable by specific fields, in the above case the title, content and the category leaving the author aside. The indexer argument specifies that we want to use the Porter Stemmer algorithm that is to allow searching your entities using word stems e.g "strangely" will also match "strange". We include stemmers for English and German.

Nonrel-search is not limited to allow only one index. You can create multiple independent indexes (each with its own fields) for one single model. One possible application of this is to have an index for the title only and another index for all fields. Like on Ebay which allows their users to include "title and description" into the user's search you can now allow your users to search only by title or by all fields.

So now let's assume we have a post with the title 'Greetings' and the content 'Hello little world' saved in our database, then we can find it by calling

# saving an entity will create the search index Post(title='Greetings', content='Hello little world').save() # ... results = Post.search_index.search('hello greeting') # results[0] should be our first "Hello little world" post

Here, "greeting" (without "s") matched the title because of the porter stemmer and obviously "hello" matched the content. The result is a Query like object you can add additional filters to:

# ... results.filter(author='Itachi') # now results should only contain entities with author set to 'Itachi'

Ah, another possible indexer is 'startswith' which allows you to use word prefix search, though you should use only on short texts.