主要字段名称(文档=True)
Django Haystack的文档说:
**Warning**
When you choose a document=True field, it should be consistently named across all of your SearchIndex classes to avoid confusing the backend. The convention is to name this field text.
There is nothing special about the text field name used in all of the examples. It could be anything; you could call it pink_polka_dot and it won’t matter. It’s simply a convention to call it text.
但是我不太明白这是什么意思。这是他们的示例模型:
import datetime
from haystack import indexes
from myapp.models import Note
class NoteIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
author = indexes.CharField(model_attr='user')
pub_date = indexes.DateTimeField(model_attr='pub_date')
def get_model(self):
return Note
def index_queryset(self, using=None):
"""Used when the entire index for model is updated."""
return self.get_model().objects.filter(pub_date__lte=datetime.datetime.now())
我引用的文本是指我自己的模型的主要字段,意思是我应该把它叫做“text”,还是指在search_indexes.py中定义的类呢?
如果是指search_indexes.py中的类,那么在上面的例子中,它附加的字段名在哪里呢?它没有model_attr啊!
text = indexes.CharField(document=True, use_template=True)
如果是指我实际应用中的模型,那我该如何重构一个有很多应用的项目,让它们的主要文本字段都叫“text”呢!
请给点建议。谢谢。
1 个回答
你的 SearchIndex
定义不需要和模型定义一一对应,它需要把不同模型的数据映射到一个共同的搜索文档中。
- 为什么文本字段需要保持一致的命名?
- 内容是怎么获取的?(为什么没有
model_attr
这个关键词)
Haystack 的文档建议你的 SearchIndex
字段在所有的 SearchIndex
定义中应该保持一致的命名,而不是说你的模型字段也需要一致。搜索索引的定义和模型的定义之间有很大的区别。你不需要,也可能不应该担心模型字段和搜索字段之间一一对应的问题。
先从你的模型退一步,想想你想要搜索什么。你会通过一个共同的搜索视图来搜索几个不同的模型吗?假设你有两个模型:
class Note(models.Model):
title = models.CharField(max_length=40)
body = models.TextField()
class Memo(models.Model):
subject = models.CharField(max_length=50)
content = models.TextField()
author = models.ForeignKey(StaffMember)
我们想创建一个简单的搜索视图,只搜索模型的主要内容以及内容对象的标题或名称(名称、标题、主题等)。
这是一个糟糕的例子(不要这样做):
class NoteIndex(indexes.SearchIndex, indexes.Indexable):
body = indexes.CharField(document=True, use_template=True)
title = indexes.CharField(model_attr='title')
def get_model(self):
return Note
class MemoIndex(indexes.SearchIndex, indexes.Indexable):
content = indexes.CharField(document=True, use_template=True)
subject = indexes.CharField(model_attr='subject')
def get_model(self):
return Memo
在这个糟糕的例子中,每个搜索索引确实定义了一个主要内容字段和一个内容名称字段(标题或主题)。但是你现在怎么搜索呢?如果你根据 subject
进行查询,你会漏掉 Note
内容,反之如果你根据 body
查询也是一样。
更好的例子(这样做):
class NoteIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
title = indexes.CharField(model_attr='title')
def get_model(self):
return Note
class MemoIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
title = indexes.CharField(model_attr='subject')
def get_model(self):
return Memo
注意字段名称不一定要和模型字段名称相匹配。你只需定义哪个模型属性是 SearchIndex
字段的数据来源。
你是在搜索引擎中搜索文档,而不是在数据库中搜索行,所以 SearchIndex
定义是将数据库中的内容(一个表或多个表的查询)映射到一个搜索文档。SearchIndex
定义是一种转换,每个 SearchField
按照你的指定转换数据。
至于你问的缺少 model_attr
,这只是获取内容的一种方式。你也可以从模板中渲染文本内容,这就是上面 text
字段的作用(可以查看SearchField API 文档)。model_attr
源对于简单的字符字段效果很好。