Django i Lupy
14 July 2008
Comments
Lupy to pełnotekstowa wyszukiwarka napisana w Pythonie wzorowana na Lucene - pełnotekstowej wyszukiwarce napisanej w Javie. Obecnie projekt ten nie jest już rozwijany. Opis znajdziemy na starej stronie projektu, a pobrać możemy z mirrora Gentoo. Domyślnym zastosowaniem jest indeksowanie plików tekstowych, lecz równie łatwo można wykorzystać ją do indeksowania danych znajdujących się w bazie danych.Tworzenie indeksu
Umieść poniższy kod w jakimś widoku:# import
from lupy.indexer import Index
# tworzymy indeks "foobar", create True = nadpisuje
index = Index('foobar', create=True)
# pobieramy dane z bazy
pages = Page.objects.all()
for p in pages:
#indeksujemy po kolei strony
index.index(text=p.text, __title=p.title, _slug=p.slug)
index.optimize()
class Page(models.Model):
title = models.CharField(maxlength=255) # page real title (for title tag and h1 in templates)
slug = models.SlugField(maxlength=255, unique=True) # the wiki URL "title"
description = models.CharField(maxlength=255) # short description (meta description, some link generation)
text = models.TextField() # the page text
changes = models.CharField(maxlength=255) # description of changes, no blanks!
creation_date = models.DateTimeField(auto_now_add = True)
modification_date = models.DateTimeField(auto_now = True)
modification_user = models.CharField(maxlength=30)
modification_ip = models.CharField(maxlength=20, blank=True)
Proste Wyszukiwanie
from lupy.indexer import Index
index = Index('foobar', create=False)
# fraza - python
hits = index.find('python')
for h in hits:
# slug to nazwa podanego przy indeksowaniu pola
print 'Znalezione w ', h.get('slug')
Prawdziwe wykorzystanie
Dla widoku dodawania stron wiki dodałem kod indeksujący dodawaną stronę. Kod indeksujący wstawiłem zaraz po zapisie danych w bazie danych (tj. wszystko zwalidowane):if settings.WIKI_SEARCH_WITH_LUPY:
from lupy.indexer import Index
from os.path import isdir
if isdir('diamandaSearchCache'):
index = Index('diamandaSearchCache', create=False)
else:
index = Index('diamandaSearchCache', create=True)
index.index(text=page_data['text'].decode("utf-8"), __title=page_data['title'].decode("utf-8"), __description=page_data['description'].decode("utf-8"), _slug=page_data['slug'])
index.optimize()
Wyszukiwanie wyników jest nieco bardziej złożone - stosuję logiczne wyszukiwanie LUB dla każdego podanego we frazie wyrazu.
if data.has_key('lupy'):
from lupy.index.term import Term
from lupy.search.indexsearcher import IndexSearcher
from lupy.search.term import TermQuery
from lupy.search.boolean import BooleanQuery
index = IndexSearcher('diamandaSearchCache')
query = data['string'].split(' ')
q = BooleanQuery()
if len(query) > 1:
for a in query:
t = Term('text', a.decode("utf-8"))
tq = TermQuery(t)
q.add(tq, False, False)
else:
t = Term('text', query[0].decode("utf-8"))
tq = TermQuery(t)
q.add(tq, True, False)
hits = index.search(q)
pages = []
for h in hits:
pages.append({'title': h.get('title'),'description': h.get('description'),'slug': h.get('slug')})
pages.reverse()
return render_to_response('wiki/' + settings.ENGINE + '/search.html', {'pages': pages, 'lupy': lupy, 'string': data['string'], 'google': google, 'lupyuse': True, 'theme': settings.THEME, 'engine': settings.ENGINE})
<input type="submit" value="{% trans "boolean OR search" %}" name="lupy" />
{% if lupyuse %}
{% for page in pages %}
<img src="/site_media/wiki/img/2.png" alt="" /> <a href="/wiki/page/{{ page.slug }}/">{{ page.title }}</a> - {{ page.description }}<br />
{% endfor %}
{% endif %}
RkBlog
Comment article