当前位置: 首页 > 面试题库 >

Django Haystack字段的独特价值

东门深
2023-03-14
问题内容

我建立使用Django干草堆+ Elasticsearch +
Django的REST框架小的搜索引擎,而我试图找出重现的Django的行为QuerySetdistinct方法。

我的索引如下所示:

class ItemIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    item_id = indexes.IntegerField(faceted=True)

    def prepare_item_id(self, obj):
        return obj.item_id

我想做的事情如下:

sqs = SearchQuerySet().filter(content=my_search_query).distinct('item_id')

但是,Haystack
SearchQuerySet却没有distinct方法,所以我有点迷失了。我尝试对字段进行分面,然后使用返回item_id的s
列表查询Django ,但这会失去Elasticsearch的性能,并且也使得无法使用Elasticsearch的排序功能。

有什么想法吗?

编辑:

示例数据:

示例数据:

Item Model
==========

id  title
1   'Item 1'
2   'Item 2'
3   'Item 3'


VendorItem Model << the table in question
================

id  item_id  vendor_id  lat   lon
1   1        1          38    -122
2   2        1          38.2  -121.8
3   3        2          37.9  -121.9
4   1        2          ...   ...
5   2        2          ...   ...
6   2        3          ...   ...

如您所见,同一项目有多个VendorItem,但是在搜索时,我只希望为每个项目检索一个结果。因此,我需要该item_id列是唯一/不同的。

我尝试在item_id列上进行构面,然后执行以下查询:

facets = SearchQuerySet().filter(content=query).facet('item_id')
counts = sqs.facet_counts()

# ids will look like: [345, 892, 123, 34,...]
ids = [i[0] for i in counts['fields']['item_id']]

items = VendorItem.objects.filter(vendor__lat__gte=latMin,
    vendor__lon__gte=lonMin, vendor__lat__lte=latMax,
    vendor__lon__lte=lonMax, item_id__in=ids).distinct(
        'item').select_related('vendor', 'item')

这里的主要问题是结果仅限于100个项目,并且无法与干草堆一起排序。


问题答案:

我认为我能给您的最好建议是停止使用Haystack。

Haystack的默认后端(elasticsearch_backend.py)大多是在考虑Solr的情况下编写的。我在干草堆中发现很多烦恼,但是最大的麻烦是它将所有查询打包到一个名为query_string的东西中。使用查询字符串,他们可以使用lucene语法,但这也意味着丢失了整个Elasticsearch
DSL。lucene语法具有一些优点,尤其是您习惯使用这种语法时,但是从elasticsearch的角度来看,这是非常有限的。

此外,我认为您正在将RDBMS概念应用于搜索引擎。这并不是说您不应该获得所需的结果,但是方法通常是不同的。

如果不使用haystack,则查询和检索此数据的方式可能会有所不同,因为haystack以一种比solarsearch更适合solr的方式创建索引。

例如,在创建新索引时,haystack将为所有要加入索引的模型分配一个称为“ modelresult”的“类型”。

因此,假设您有一些实体称为Items,而另一些实体则称为vendoritems。

将它们都放在同一索引中,但将供应商项目作为一种供应商项目,并将具有某种项目的项目作为项目可能是合适的。

查询时,您将根据其余端点进行查询,例如localhost:9200/index/type (query)。干草堆的实现方式是通过Django内容类型模块。因此,存在一个名为“
django_ct”的字段,该字段会在干草堆中查询并附加到您在仅查找唯一项时可能进行的任何查询。

为了说明上述内容:

该端点搜索所有索引

`localhost:9200/`

该端点在索引中的所有类型中进行搜索:

`localhost:9200/yourindex/`

该端点在索引内搜索类型:

`localhost:9200/yourindex/yourtype/`

并且此端点在索引内搜索两种指定的类型:

`localhost:9200/yourindex/yourtype,yourothertype/`

回到干草堆,您可以通过在查询中添加django_ct来获得唯一值,但这可能不是您想要的。

您真正想做的是构面,也许您想使用术语构面。这在干草堆中可能是一个问题,因为它A.)分析了所有文本,而B.)将store =
True应用于所有字段(实际上不是您想要在elasticsearch中执行的操作,而是您经常想在solr中执行的操作)。

您可以在Elasticsearch中对方面结果进行排序(http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-
facets-terms-
facet.html#_ordering)

我并不是说要成为大海捞针。我认为它在概念上做了很多事情。如果您需要做的就是索引一个模型(例如说一个博客)并让它快速返回结果,那就特别好。

也就是说,我强烈建议您使用elasticutils。haystack中的某些概念很相似,但是它使用搜索dsl而不是query_string(但是如果需要,您仍然可以使用query_string)。

请注意,默认情况下,我认为您不能使用elasticutils来订购刻面,但是您可以仅传入要处理的刻面的python字典facet_raw(这是我认为您无法在干草堆中进行的操作)。

最后一个选择是创建自己的干草堆后端,从现有后端继承,并仅向.facet()方法添加一些功能以允许根据上述dsl进行排序



 类似资料:
  • 问题内容: 在Python 2.x中,当您要将一个方法标记为抽象时,可以这样定义它: 然后,如果您忘记覆盖它,则会收到一个很好的提醒异常。是否存在将字段标记为抽象的等效方法?还是在您可以做的所有工作中在类文档字符串中说明? 起初我以为可以将字段设置为NotImplemented,但是当我查看它的实际用途(进行大量比较)时,它似乎很脏。 问题答案: 是的你可以。使用装饰器。例如,如果您有一个名为“e

  • 问题内容: 如何更新字段以为现有价值增加价值? 例如我有 表名: 有没有一种方法可以简单地为信用增加价值? 喜欢 我想将7加到4,以便credit = 11,其中id =‘1’ ,该怎么做? 问题答案:

  • 问题内容: 我在下面有一个模型,我想获得所有不同的值。SQL等效为 我知道在Python中我可以做到 但这需要我将区域项目从查询中移出到另一个列表中,然后针对该列表运行集合(听起来效率很低),如果我在数据存储区中的位置1001有一个不同的项目,则由于提取限制为1000。 我想获取数据存储区中area的所有不同值,以将其作为链接转储到屏幕上。 问题答案: 数据存储区无法在单个查询中为您执行此操作。数

  • 问题内容: 考虑表学生: 使用以下查询,我们得到: 由此我们将得到: 我们如何得到类似的东西 问题答案: 这应该做的工作

  • 问题内容: 我们需要从Typescript中的node.js代码中调用REST API,并希望具有用于请求和响应的相应类型。不幸的是,给定接口的JSON包含以下字段: 我们被告知,这是由于另一端的自动化“ JSONifier”的局限性而无法更改的。我们如何设置适合于此的接口?以下显然不起作用: 问题答案: 就像JS对象一样,您可以用引号将名称引起来,如下所示:

  • 本文向大家介绍MongoDB查询添加一个新字段,并将价格(字段)结果除以其中的特定数字连接起来,包括了MongoDB查询添加一个新字段,并将价格(字段)结果除以其中的特定数字连接起来的使用技巧和注意事项,需要的朋友参考一下 要添加新字段,请使用MongoDB中的$addFields。让我们创建一个包含文档的集合- 在find()方法的帮助下显示集合中的所有文档- 这将产生以下输出- 以下是添加新字