在Django中高效地搜索外键树
我使用ForeignKey从模型中创建了一个树状结构 联系。例如:在Django中高效地搜索外键树,django,orm,Django,Orm,我使用ForeignKey从模型中创建了一个树状结构 联系。例如: Model Person: name = CharField Model Book: name = CharField author = FK(Person) Model Movie: name = CharField director = FK(Person) Model Album: name = CharField director =
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字段,即不仅仅是“名称”
我想做的是有一个搜索函数,这样就有一个字符串
提供,它将返回与Person对象匹配的任何Person
本身,或任何子节点中的字段。瞧,如果被打败了,那就是
字符串,以及与相册关联的歌曲的名称
人员匹配时,将返回该人员
到目前为止,我所做的工作如下:
对于任何叶节点,都有一个带有搜索方法的管理器对象
比如:
return Song.objects.filter(name__icontains=search_string)
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
然后对于根节点Person和任何内部节点,还有一个
带有搜索方法的管理器对象,该搜索方法类似于:
return Song.objects.filter(name__icontains=search_string)
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
正如您所想象的,一旦到达根节点,就会释放一个
大量的查询,而且效率很低。我会很漂亮的
如果没有更好的方法,我会很惊讶。。。一个想法是
在树的顶部有一个手动搜索的搜索方法
通过一切,但一个看起来很混乱,虽然可能更多
高效和b最好能够搜索单个节点
武断地
这么说来,有什么更有效的方法可以获得
我想去哪里而不是我的白痴方法 也许最好将搜索功能外包给一个专门的工具,如or。两个搜索框架都有项目,分别与Django和Django集成。与使用包含许多联接和子查询的复杂SQL查询相比,您将获得更好的性能。也许最好将搜索功能外包给专用工具,如or。两个搜索框架都有项目,分别与Django和Django集成。与使用包含多个联接和子查询的复杂SQL查询相比,您将获得更好的性能。是另一种选择。是另一种选择。我认为使用基本ORM所能做的任何事情都不会真正有效,基本上,您将在具有大量连接的不同模型上运行一系列过滤器查询 如果您的目标是高性能、长期的解决方案,那么最好的办法就是在内存中创建一个对象存储库。我认为在基本SQL中没有任何方法可以使这些查询高效,特别是当您处理大量行时
为您的子对象章节、歌曲等创建一个非规范化的表,其中包含您的所有个人和书籍/专辑数据,这可能是一个潜在的中期解决方案,这将需要一些奇特的SQL基础工作,这可能不是Django Core的一部分。我认为您可以用基本ORM做的任何事情都不会真正有效,基本上,您将在具有大量连接的不同模型上运行一系列过滤器查询 如果您的目标是高性能、长期的解决方案,那么最好的办法就是在内存中创建一个对象存储库。我认为在基本SQL中没有任何方法可以使这些查询高效,特别是当您处理大量行时
为您的子对象章节、歌曲等创建一个非规范化的表,其中包含您的所有个人和书籍/专辑数据,这可能是一个潜在的中期解决方案,这将需要一些花哨的SQL步法,这可能不是Django Core的一部分。好吧,如果您不想设置像whoosh这样的搜索引擎,那么您可以使用Q 这需要对字段进行一点硬编码,而不是简单地遍历所有字段
>>> q = Q()
>>> q = q | Q( fk__fk__field__icontains = searchTerm )
>>> q = q | ...
...
>>> qs = Model.objects.filter(q)
好吧,如果你不想建立像whoosh这样的搜索引擎,那么你可以使用Q 这需要对字段进行一点硬编码,而不是简单地遍历所有字段
>>> q = Q()
>>> q = q | Q( fk__fk__field__icontains = searchTerm )
>>> q = q | ...
...
>>> qs = Model.objects.filter(q)
我考虑过反规范化,但不幸的是,我真的没有能力在数据库的这一部分对表结构进行篡改。我想基本的Django ORM不会有太好的选择。是的,去规范化对Django来说是陌生的,事实上,尽管ORM很简单,但它也存在一些超大规模的性能问题,特别是如果你想进行复杂的搜索。看看卡尔·亨德森在DjangoCon的主旨演讲,他谈到了其中的一些事情。对于任何使用Django的人来说,这都是一个很好的听力工具。谢谢你的指点。对我来说,ORM对我来说是一个积极的因素-DB本身对于ORM来说是次优的,但是总体流量太低,以至于它平衡了,在一些地方我不使用ORM。。。考虑到这让我的生活轻松多了,我还是要接受它这恰好是我遇到的问题之一。我考虑过反规范化,但不幸的是,我没有能力在这一部分中对表结构进行修改
DB的一部分。我想基本的Django ORM不会有太好的选择。是的,去规范化对Django来说是陌生的,事实上,尽管ORM很简单,但它也存在一些超大规模的性能问题,特别是如果你想进行复杂的搜索。看看卡尔·亨德森在DjangoCon的主旨演讲,他谈到了其中的一些事情。对于任何使用Django的人来说,这都是一个很好的听力工具。谢谢你的指点。对我来说,ORM对我来说是一个积极的因素-DB本身对于ORM来说是次优的,但是总体流量太低,以至于它平衡了,在一些地方我不使用ORM。。。考虑到这让我的生活轻松多了,我还是要接受它这恰好是一个问题。我一直在研究Woosh和Sphinx,它们似乎都比Solr容易设置,虽然我当前的设置太慢,但我不需要超高性能。我一直在研究Woosh和Sphinx,它们似乎都比Solr容易设置,虽然我当前的设置太慢,但我不需要超高性能。哪种感觉更容易处理?这基本上就是我正在做的。一旦它开始变得非常深入,我就开始在每一层封装一个迷你搜索,当你向树的根移动时,Q调用涉及到其他搜索方法。只需在根级别执行Q并手动进入fk,速度更快,但仍然相当粗糙。这基本上就是我正在做的。一旦它开始变得非常深入,我就开始在每一层封装一个迷你搜索,当你向树的根移动时,Q调用涉及到其他搜索方法。只是在根级别执行Q并手动进入fk的速度更快,但仍然相当粗糙。