MongoDB ja Sphinx sopivat huonosti yhteen, koska Sphinx edellyttää (typerästi) jokaisen indeksoitavan dokumentin olevan tunnistettavissa 32- tai 64-bittisellä numerolla. MongoDB:n ObjectId-tunnisteet ovat 96-bittisiä, joten ne eivät mahdu Sphinxiin.

Tämän vuoksi päätin luopua Sphinxistä tämän saitin tekstihaussa ja pyöräytin nopeasti kasaan oman MongoDB-pohjaisen haun. MongoDB ei suoraan tue täystekstihakuja, mutta mahdollistaa niiden toteuttamisen itse.

Oma quick-and-dirty-ratkaisuni perustuu artikkelien sanojen pilkkomiseen dict-objekteiksi, jotka sisältävät kunkin sanan lukumäärän. Pilkkominen tehdään tällaisella Python-koodilla, josta on suhteellisen helppo säätää sanat erottelevia erikoismerkkejä:

WORDS_RE = re.compile(ur'[\x00- !"\'()*+,./:;<=>$?-]+')
self.words = dict(Counter([word for word in WORDS_RE.split(strip_tags(self.rendered_body).strip().lower()) if word]))

Artikkelien etsiminen puolestaan hoituu django-mongodb-enginen raw_query-metodilla:

articles = Article.objects.raw_query(dict([('words.' + word, {'$gt': 0}) for word in WORDS_RE.split(q.strip().lower()) if word]))

Hakusanojen laittaminen suoraan osaksi MongoDB-kyselyn kenttänimiä hieman hirvittää, mutta ei kai siinä periaatteessa pitäisi olla riskiä. Ongelmaksi jää vielä myös hakutulosten järjestäminen sanamäärien mukaan, taivutusmuotojen hoitaminen ja niin edelleen.

Published 29.12.2011