姜戈。如何return QuerySet order_by 一个模糊wuzzy方法的结果?
Django. How to return QuerySet order_by result of a fuzzy wuzzy method?
这是我的模型:
class Item(models.Model):
status = models.IntegerField(choices=STATUS_CHOICES, default=3)
def __str__(self):
return 'Item: {0}'.format(self.id)
class Name(models.Model):
name = models.CharField(, max_length=600, default='')
item = models.ForeignKey(Item, db_index=True, blank=True, null=True)
main = models.BooleanField(default=False)
def __str__(self):
return '{}'.format(self.name)
我想查询集合项目,所以 returns X 项目按 Fuzzy wuzzy. 排序
基本上,我需要找到匹配的项目并合并它们。
我尝试创建字典,但速度非常慢。我有大约 80 000 件商品,而且还在增加中。
我试过类似的东西:
items = Item.objects.filter(status=3)
.annotate( score=fuzz.ratio(query,i.name_set.all().first().name))
.order_by('-score')
谁能给我一些关于这个话题的信息?
谢谢
如果数据库中有 80.000 个条目,您必须考虑以下选项:
(A) 让数据库排序(最好使用一些预先创建的索引)并且 return 仅选择行。这允许通过数据库进行分页。
(B) return 尽可能快地从数据库中获取所有内容,并在 RAM 中对所有 80.000 进行排序。如果你想坚持使用 python 模块 FuzzyWuzzy,你将不得不这样做。但正如您现在所经历的那样,这可能不会很快。您必须自己进行分页。
[FuzzyWuzzy] uses Levenshtein Distance to calculate the differences between sequences in a simple-to-use package.
如果您使用 PostgreSQL 作为后端,您可以使用这里描述的 levenshtein 函数:
https://www.postgresql.org/docs/9.1/static/fuzzystrmatch.html
似乎有对 Django 的贡献来集成它:
https://github.com/django/django/pull/4825
TrigramSimilarity 已经可用。您可以查看源代码并根据 postgres levenshtein 实现类似的东西。但我建议先尝试一下。它可能已经满足您的需求。
编辑:
一般来说,对于这种大小或更大的表,请确保您的数据库在需要的地方有索引并使用它们。例如:Django 的 __icontains
过滤器没有被 Django 的 db_index
覆盖。您必须自己在该列上添加一个三元组索引。
您当前的代码可能需要这么长时间,因为查询已经花费了不必要的时间。
如果您正在使用 PostgreSQL,您可以使用 Trigram Similar
trigram_similar
查找允许您使用专用 PostgreSQL 扩展执行三元组查找,测量共享的三元组(三个连续字符)的数量。
安装:
更新您的 settings.py
::
INSTALLED_APPS = [
...
'django.contrib.postgres',
]
添加新迁移::
python manage.py makemigrations --empty yourappname
将创建一个新的迁移文件,例如:migrations/0002_auto_<date>_<time>.py
。更新它::
from django.db import migrations
from django.contrib.postgres.operations import TrigramExtension
class Migration(migrations.Migration):
dependencies = [
...
]
operations = [
TrigramExtension(),
]
现在迁移:
./manage.py migrate
现在您可以使用 trigram_similar
查找 CharField
和 TextField
例如:
>>> City.objects.filter(name__trigram_similar="Middlesborough")
['<City: Middlesbrough>']
这是我的模型:
class Item(models.Model):
status = models.IntegerField(choices=STATUS_CHOICES, default=3)
def __str__(self):
return 'Item: {0}'.format(self.id)
class Name(models.Model):
name = models.CharField(, max_length=600, default='')
item = models.ForeignKey(Item, db_index=True, blank=True, null=True)
main = models.BooleanField(default=False)
def __str__(self):
return '{}'.format(self.name)
我想查询集合项目,所以 returns X 项目按 Fuzzy wuzzy. 排序 基本上,我需要找到匹配的项目并合并它们。
我尝试创建字典,但速度非常慢。我有大约 80 000 件商品,而且还在增加中。
我试过类似的东西:
items = Item.objects.filter(status=3)
.annotate( score=fuzz.ratio(query,i.name_set.all().first().name))
.order_by('-score')
谁能给我一些关于这个话题的信息? 谢谢
如果数据库中有 80.000 个条目,您必须考虑以下选项:
(A) 让数据库排序(最好使用一些预先创建的索引)并且 return 仅选择行。这允许通过数据库进行分页。
(B) return 尽可能快地从数据库中获取所有内容,并在 RAM 中对所有 80.000 进行排序。如果你想坚持使用 python 模块 FuzzyWuzzy,你将不得不这样做。但正如您现在所经历的那样,这可能不会很快。您必须自己进行分页。
[FuzzyWuzzy] uses Levenshtein Distance to calculate the differences between sequences in a simple-to-use package.
如果您使用 PostgreSQL 作为后端,您可以使用这里描述的 levenshtein 函数:
https://www.postgresql.org/docs/9.1/static/fuzzystrmatch.html
似乎有对 Django 的贡献来集成它: https://github.com/django/django/pull/4825
TrigramSimilarity 已经可用。您可以查看源代码并根据 postgres levenshtein 实现类似的东西。但我建议先尝试一下。它可能已经满足您的需求。
编辑:
一般来说,对于这种大小或更大的表,请确保您的数据库在需要的地方有索引并使用它们。例如:Django 的 __icontains
过滤器没有被 Django 的 db_index
覆盖。您必须自己在该列上添加一个三元组索引。
您当前的代码可能需要这么长时间,因为查询已经花费了不必要的时间。
如果您正在使用 PostgreSQL,您可以使用 Trigram Similar
trigram_similar
查找允许您使用专用 PostgreSQL 扩展执行三元组查找,测量共享的三元组(三个连续字符)的数量。
安装:
更新您的 settings.py
::
INSTALLED_APPS = [
...
'django.contrib.postgres',
]
添加新迁移::
python manage.py makemigrations --empty yourappname
将创建一个新的迁移文件,例如:migrations/0002_auto_<date>_<time>.py
。更新它::
from django.db import migrations
from django.contrib.postgres.operations import TrigramExtension
class Migration(migrations.Migration):
dependencies = [
...
]
operations = [
TrigramExtension(),
]
现在迁移:
./manage.py migrate
现在您可以使用 trigram_similar
查找 CharField
和 TextField
例如:
>>> City.objects.filter(name__trigram_similar="Middlesborough")
['<City: Middlesbrough>']