2010-09-11 2 views
0

Мне нужно быстро найти слова для веб-приложения, которое я пишу в Django. Я думал о том, чтобы поместить каждого символа слова в собственное целое поле, индексированное положением.Django DB design to glob words быстро

class Word(models.Model): 
    word = models.CharField(max_length=5) 
    length = models.IntegerField() 

    c0 = models.IntegerField(blank=True, null=True) 
    c1 = models.IntegerField(blank=True, null=True) 
    c2 = models.IntegerField(blank=True, null=True) 
    c3 = models.IntegerField(blank=True, null=True) 
    c4 = models.IntegerField(blank=True, null=True) 

    mapping = [c0, c1, c2, c3, c4,] 

    def save(self): 
     self.length = len(self.word) 
     for (idx, char) in enumerate(self.word): 
      self.mapping[idx] = ord(char) 
     models.Model.save(self) 

Тогда я мог бы делать запросы, как Word.objects.filter(length=4, mapping[2]=ord('A')) найти все слова длины четыре, которые имеют A в третьем положении.

Я не совсем уверен в дизайне и некоторых механиках, поэтому я думал, что попрошу предложения здесь до того, как я поеду и попытаюсь его реализовать. Я не совсем уверен в синтаксисе для создания запросов.

Итак, я предполагаю, что вопросы будут

  1. Есть ли у вас какие-либо предложения по дизайну?
  2. Будет mapping[2] работы?
  3. Смогу ли я передать словарь в команду фильтра, чтобы у меня могло быть переменное количество аргументов ключевого слова?

Спасибо!

+0

Можете ли вы рассказать подробнее, сколько слов это и почему вам нужно быстро найти их и как быстро? –

+0

Я оптимизирую программу удовлетворения ограничений обратного отслеживания для генерации кроссвордов. Сейчас у меня около 42 000 уникальных слов и фраз. Они лишены всего, кроме буквенных символов в верхнем регистре и хранятся во всех кепках.Я запускал cProfile по моему алгоритму, и сейчас я трачу большую часть времени на получение кандидатов из словаря (в настоящее время я использую fnmatch в списке слов - что-то быстрое и грязное, чтобы увидеть, правильно ли я понял, до того, как начал оптимизацию) , Чем быстрее я это сделаю, тем лучше. –

ответ

0

Будет ли отображение [2] работать?

Нет, это не так.

Могу ли я передать словарь в команду фильтра, чтобы у меня могло быть переменное количество аргументов ключевого слова?

Конечно. Например:

conditions = dict(word__startswith = 'A', length = 5) 
Word.objects.filter(**conditions) 

найдет все Word экземпляров, начиная с A и пяти символов.

У вас есть предложения по дизайну?

Это чувствует ко мне, как случай преждевременной оптимизации. Я подозреваю, что для умеренных объемов данных вы должны иметь возможность комбинировать подходящую функцию базы данных с фильтром Django, чтобы получить то, что вам нужно.

Например:

, чтобы найти все слова длины четыре, которые имеют A в третьем положении.

Вы можете комбинировать фильтр Django с (Postgresql's) strpos.

contains, position = 'A', 3 
where = ["strpos(word, '%s') = %s" % (contains, position)] 
Word.objects.filter(length = 4, word__contains = contains).extra(where = where) 
+0

Спасибо за ваш ответ! Я имею дело с около 42 000 слов (в ближайшем будущем я планирую иметь еще много), и для вызова бэкэнд мне нужно сделать около шести-восьми сотен частичных поисковых запросов. word__startswith не будет работать, потому что мне нужно найти такие шаблоны, как «?? SH ??» среди прочего (я генерирую кроссворды, я должен был сказать это - извините). Я не знал о фильтре strpos с Postgresql. Это работает с sqlite3 или nonrel/appengine? Еще раз спасибо! –

+0

'Это работает с sqlite3 или nonrel/appengine?': Извините, я не знаю, есть ли эквивалент 'strpos' для SQLite или nonrel/appengine. –

+0

Спасибо! Я использовал ваше предложение указать условия, используя словарь! –