我使用ForeignKey从模型中创建了树状结构 联系。举个例子:
Model Person:
name = CharField
Model Book:
name = CharField
author = FK(Person)
Model Movie:
name = CharField
director = FK(Person)
Model Album:
name = CharField
director = FK(Person)
Model Chapter:
name = CharField
book = FK(Book)
Model Scene:
name = CharField
movie = FK(Movie)
Model Song:
name = CharField
album = FK(Album)
这里需要注意的是,真实的结构既更深入,也更广泛 节点可能有多个非FK字段(即不仅仅是'name')。
我想要做的是有一个搜索功能,以便有一个字符串 提供的将返回任何匹配Person对象的Person 本身,或任何子节点中的字段。 IOW,如果“击败它”就是 字符串,以及与相关联的相关联的歌曲的名称 人匹配,该人将被退回。
到目前为止我所做的是以下内容:
对于任何叶节点,请使用具有搜索方法的Manager对象 类似的东西:
return Song.objects.filter(name__icontains=search_string)
然后对于根节点(Person)和任何内部节点,还有一个 具有search()方法的Manager对象,如下所示:
class AlbumManager(models.Model):
def search(self, search_string):
from_songs = Album.objects.filter(song__in=Song.objects.search(search_string))
return Album.objects.filter(name__icontains=search_string)|from_songs
正如您可能想象的那样,一旦到达根节点,就会释放出一个 大量的查询,实在是效率低下。我会很漂亮 如果没有更好的方法来做到这一点感到惊讶......一个想法就是公正 在树的顶部有一个search()方法,可以手动搜索 通过一切,但a)看起来非常混乱(虽然可能更多 有效的)和b)能够搜索单个节点会很高兴 任意。
所有这一切都说,什么是更有效的获取方法 我想在哪里而不是我的骨头方法?
答案 0 :(得分:2)
将搜索功能外包给Woosh或Sphinx等专用工具可能会更好。两个搜索框架的项目都将它们与Django(分别为django-haystack和django-sphinx)集成在一起。与具有许多连接和子查询的复杂SQL查询相比,您将获得更好的性能。
答案 1 :(得分:2)
好吧,如果您不想设置像whoosh这样的搜索引擎,那么您可以使用Q
http://docs.djangoproject.com/en/dev/topics/db/queries/#complex-lookups-with-q-objects
这将涉及对字段进行硬编码,而不是简单地遍历所有字段。
>>> q = Q()
>>> q = q | Q( fk__fk__field__icontains = searchTerm )
>>> q = q | ...
...
>>> qs = Model.objects.filter(q)
答案 2 :(得分:1)
Django Solr是另一种选择。
答案 3 :(得分:1)
我认为你对基本的ORM做的任何事情都不会真正有效,你基本上会在不同的模型上运行一系列的filter()查询,并且有很多JOIN。< / p>
如果您的目标是高性能,长期解决方案,最好的办法是在内存中创建一个对象存储库。我没有看到基本SQL中的任何方法可以使这些查询有效,特别是如果你正在使用大量的行。
为包含所有Person和Book / Album数据的子对象(章节,歌曲等)创建非规范化表可能是一个潜在的中期解决方案,这将需要一些可能不属于您的一些奇特的SQL步法Django Core。