- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
django.contrib.postgres 的新 TrigramSimilarity 特性非常适合我遇到的问题。我将它用于搜索栏以查找难以拼写的拉丁名称。问题是有超过 200 万个名字,搜索时间比我想要的要长。
我想在 postgres documentation 中描述的三元组上创建一个索引.
但我不确定如何以 Django API 使用它的方式执行此操作。对于 postgres 文本搜索,有关于如何创建索引的描述,但没有关于 trigram similarity 的描述。 .
这是我现在拥有的:
class NCBI_names(models.Model):
tax_id = models.ForeignKey(NCBI_nodes, on_delete=models.CASCADE, default = 0)
name_txt = models.CharField(max_length=255, default = '')
name_class = models.CharField(max_length=32, db_index=True, default = '')
class Meta:
indexes = [GinIndex(fields=['name_txt'])]
在 View 的get_queryset
方法中:
class TaxonSearchListView(ListView):
#form_class=TaxonSearchForm
template_name='collectie/taxon_list.html'
paginate_by=20
model=NCBI_names
context_object_name = 'taxon_list'
def dispatch(self, request, *args, **kwargs):
query = request.GET.get('q')
if query:
try:
tax_id = self.model.objects.get(name_txt__iexact=query).tax_id.tax_id
return redirect('collectie:taxon_detail', tax_id)
except (self.model.DoesNotExist, self.model.MultipleObjectsReturned) as e:
return super(TaxonSearchListView, self).dispatch(request, *args, **kwargs)
else:
return super(TaxonSearchListView, self).dispatch(request, *args, **kwargs)
def get_queryset(self):
result = super(TaxonSearchListView, self).get_queryset()
#
query = self.request.GET.get('q')
if query:
result = result.exclude(name_txt__icontains = 'sp.')
result = result.annotate(similarity=TrigramSimilarity('name_txt', query)).filter(similarity__gt=0.3).order_by('-similarity')
return result
最佳答案
我找到了一个 12/2020 article这样使用最新版本的 Django ORM:
class Author(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
class Meta:
indexes = [
GinIndex(
name='review_author_ln_gin_idx',
fields=['last_name'],
opclasses=['gin_trgm_ops'],
)
]
如果像最初的发帖者一样,您希望创建一个与 icontains 一起使用的索引,则必须索引列的 UPPER(),这需要来自 OpClass 的特殊处理。 :
from django.db.models.functions import Upper
from django.contrib.postgres.indexes import GinIndex, OpClass
class Author(models.Model):
indexes = [
GinIndex(
OpClass(Upper('last_name'), name='gin_trgm_ops'),
name='review_author_ln_gin_idx',
)
]
灵感来自 old article在这个问题上,我登陆了current one它为 GistIndex
提供了以下解决方案:
更新:从 Django-1.11 开始,事情似乎更简单了,如 this answer和 django docs建议:
from django.contrib.postgres.indexes import GinIndex
class MyModel(models.Model):
the_field = models.CharField(max_length=512, db_index=True)
class Meta:
indexes = [GinIndex(fields=['the_field'])]
来自 Django-2.2 ,属性 opclasses
将在 class Index(fields=(), name=None, db_tablespace=None, opclasses=())
中可用为此目的。
from django.contrib.postgres.indexes import GistIndex
class GistIndexTrgrmOps(GistIndex):
def create_sql(self, model, schema_editor):
# - this Statement is instantiated by the _create_index_sql()
# method of django.db.backends.base.schema.BaseDatabaseSchemaEditor.
# using sql_create_index template from
# django.db.backends.postgresql.schema.DatabaseSchemaEditor
# - the template has original value:
# "CREATE INDEX %(name)s ON %(table)s%(using)s (%(columns)s)%(extra)s"
statement = super().create_sql(model, schema_editor)
# - however, we want to use a GIST index to accelerate trigram
# matching, so we want to add the gist_trgm_ops index operator
# class
# - so we replace the template with:
# "CREATE INDEX %(name)s ON %(table)s%(using)s (%(columns)s gist_trgrm_ops)%(extra)s"
statement.template =\
"CREATE INDEX %(name)s ON %(table)s%(using)s (%(columns)s gist_trgm_ops)%(extra)s"
return statement
然后您可以像这样在您的模型类中使用它:
class YourModel(models.Model):
some_field = models.TextField(...)
class Meta:
indexes = [
GistIndexTrgrmOps(fields=['some_field'])
]
关于python - 在 Django 模型中使用 Trigram (gin_trgm_ops) 创建 Gin 索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44820345/
main_text 是一个列表列表,其中包含已被词性标记的句子: main_text = [[('the', 'DT'), ('mad', 'JJ'), ('hatter', 'NN'), ('li
目标是按相似度顺序快速搜索相似值。 这是 Django 中的查询:Model.objects.annotate(similarity=TrigramSimilarity('field_name', q
我想像 google suggestions 这样的文本搜索. 我正在使用 PostgreSQL因为神奇Postgis . 我正在考虑使用 FTS , 但我看到它无法搜索 partial words
我在使用 Java 获取 trigrams 时遇到了一些问题。我的程序目前可以很好地获取 bigrams,但是当我尝试实现相同的方法结构并将其更改为获取 trigrams 时,它似乎无法正常工作。我希
我有这个例子,我想知道如何得到这个结果。我有文本并将其标记化,然后像这样收集二元组、三元组和四元组 import nltk from nltk import word_tokenize from nl
我创建了一个 trigram 索引,以便执行带有“like %text%”条件的查询,但 PostgreSQL 9.6 不使用该索引来执行查询。 CREATE EXTENSION pg_trgm;
我正在尝试使用 LinkedHashMap 创建一个 trigram 模型>其中 Entry 是最后输入的二元组的条目(其结构为:LinkedHashMap 现在的问题是,作为一个映射,它不存储多个键
我正在我们的系统中使用 ILIKE 进行模式匹配搜索,但由于表中的记录数量,它在某些表上变得太慢了。所以我正在按照这篇文章中的说明实现三元组索引 https://www.depesz.com/2011
我能够按相似度对三元组搜索进行排序,并按相似度分数进行过滤,这意味着必须有一些客观排名与每条记录相关联。我如何访问该分数? 我使用的代码: q = "search query" # ie "hone
在我的 PostgreSQL 数据库中,我有 slides 表,其中有 name 列。我想实现搜索。我在 PostgreSQL 中尝试了三元组索引。我创建了以下索引: CREATE INDEX ind
我在 elasticsearch 上创建了一个索引,如下所示: "settings" : { "number_of_shards": 1, "number_of_replicas":
三元组索引的表,如果查询中存在大小写混合或 ILike 则不起作用。我不确定我错过了什么。有什么想法吗? (我使用的是 PostgreSQL 9.6.2) CREATE TABLE public.tb
如标题所述,我想使用空格作为分隔符来解析表中的每一行(1 列,~1k 行)。每行包含一个短语。我想列出每个短语的所有 unigrams、bigrams 和 trigrams。下面的示例数据和所需的输出
postgres trigram documentation状态: The pg_trgm module provides GiST and GIN index operator classes th
所以我已经通过 Homebrew 安装了 Postgresql,看起来 contrib 目录丢失了。我读过的所有安装 Trigram 的教程都需要这个。 $ cd /usr/local/Cellar/
我使用 pg_trgm 模块中的 similarity() 函数在 C# 中为 PostgreSQL 数据库创建了一个模糊搜索。现在我想把这个搜索移植到 MySQL 数据库,但是 MySQL 没有类似
我在 Rails 上使用 pg_search gem 实现了三元组搜索。 https://github.com/Casecommons/pg_search 问题是有时返回结果的顺序根据显示 gem 文
所以基本上我设置了一个非常简单的测试表来测试 postgresql 9.1(股票 Debian 稳定版)中的三元组和全文索引功能。 下面是表和索引定义: -- Table: fulltextproba
我有一个单字母组(单个单词)、双字母组(两个单词)和三字母组(三个单词)的列表,我从一堆文档中提取出来。我的目标是静态分析报告,以及搜索我可以在这些文档上使用。 John Doe Xeon 5668x
我知道如何使用 NLTK 获取二元组和三元组搭配,并将它们应用到我自己的语料库中。代码如下。 我唯一的问题是如何打印出带有 PMI 值的 birgram?我多次搜索 NLTK 文档。要么我遗漏了什么,
我是一名优秀的程序员,十分优秀!