Django - 使用PostgreSQL和Elasticsearch进行全文搜索

4

我有一个由 DjangoDjango REST Framework 支持的RESTful API(与 PostgreSQL 数据库后端通信),支持在特定模型上进行过滤。

现在我想添加全文搜索功能。

是否可以使用 Elasticsearch 进行全文搜索,然后在这些搜索结果之上应用现有的API过滤器?

2个回答

4
我建议您考虑只使用PostgreSQL来完成您所要求的操作。在我看来,这是最好的解决方案,因为您将直接在PostgreSQL中拥有数据和搜索索引,并且不必安装和维护其他软件(如Elasticsearch),也不需要保持数据和索引同步。
以下是在Django中使用PostgreSQL执行全文搜索的最简代码示例:
Entry.objects.filter(body_text__search='Cheese')

对于使用Django与PostgreSQL进行全文搜索的基本文档,您可以使用官方文档:全文搜索。如果您想进一步深入,可以阅读我写的一篇文章Django中使用PostgreSQL的全文搜索。请保留HTML标签。

0

你的问题太广泛了,无法用代码回答,但肯定是可以解决的。

你可以轻松地搜索你的 Elasticsearch,以匹配你的全文检索条件。

然后获取这些行的 PK 字段(或任何其他候选键,用于唯一标识 PostgreSQL 数据库中的行),并过滤你的 Django ORM 支持的模型,以匹配那些你从 Elasticsearch 中找到的 PK。

伪代码如下:

def get_chunk(l, length):
    for i in xrange(0, len(l), length):
        yield l[i:i + length]

res = es.search(index="index", body={"query": {"match": ...}})

pks = []
for hit in res['hits']:
    pks.append(hit['pk'])

for chunk_10k in get_chunk(pks, 10000):
    DjangoModel.objects.filter(pk__in=chunk_10k, **the_rest_of_your_api_filters)

编辑
为了解决在弹性查询中可能会找到大量PK的情况,您可以定义一个生成器,该生成器产生结果的连续10K行,以便您不会超出DB查询限制,并确保最佳更新性能。 我使用名为get_chunk的函数定义它。

对于redis、mongodb等替代方案,类似的方法也可以奏效...


1
是的,这可能是一个解决方案。不过也有潜在问题。例如,如果搜索返回数千个结果 https://dev59.com/lnNA5IYBdhLWcg3wVcFx。 - Dušan Maďar
@dm295 是 Elasticsearch 一系列问题中的第一个。 - Paolo Melchiorre
1
@dm295 当然。您应该有一种方法来分块请求超过n-K pks的postgresql DB。我对MongoDB有同样的要求,并发现使用10K〜50K个块的__in查询可以获得最佳性能。此外,MongoDB每个查询的限制为16Mbs,在许多情况下,执行普通的__in将导致失败。这很容易做到,我会进行编辑以防万一。 - SpiXel
@DušanMaďar,我今天偶然发现了这个问题,并想到你可能没有得到任何反馈。你有找到更好的解决方案吗?如果你能分享任何比这个更好的实现方案(而不是放弃postgresql之类的),那就太完美了。谢谢。 - SpiXel
1
@SpiXel 基本上我们选择了仅使用 ES 进行搜索,并不得不重写过滤器等内容以使其与 ES 兼容。 - Dušan Maďar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接