如果我错了,请告诉我,但我认为 solr 只需要 schema.xml 中已经提到的字段。因此,如果我有一个名为“title”的字段,我需要在架构中提及这一点。
在 Sunspot 的文档中没有提到修改 schema.xml。我只是想知道 Sunspot 如何修改 schema.xml 允许将自定义字段输入到索引中。
我也知道 Sunspot 使用 RSolr 来做事。因此,如果有一种方法可以使用 RSolr 修改架构并将数据从 DB 重新加载到 Solr,请告诉我。
如果我错了,请告诉我,但我认为 solr 只需要 schema.xml 中已经提到的字段。因此,如果我有一个名为“title”的字段,我需要在架构中提及这一点。
在 Sunspot 的文档中没有提到修改 schema.xml。我只是想知道 Sunspot 如何修改 schema.xml 允许将自定义字段输入到索引中。
我也知道 Sunspot 使用 RSolr 来做事。因此,如果有一种方法可以使用 RSolr 修改架构并将数据从 DB 重新加载到 Solr,请告诉我。
正如 karmajunkie 所暗示的,Sunspot 使用自己的标准模式。我将在这里更详细地介绍它的工作原理。
出于本次讨论的目的,Solr 模式主要由两部分组成:类型定义和字段定义。
定义type
通过指定类型的名称、该类型的 Java 类以及在某些类型(特别是文本)的情况下,通过指定如何处理该类型的 XML 的从属块来设置类型。
定义field
允许您定义字段的名称,以及该字段中包含的值类型的名称。这允许 Solr 将文档中字段的名称与其类型和一些其他选项相关联,从而使该字段的值应如何在索引中进行处理。
Solr 还支持dynamicField
定义,而不是静态字段名称,它允许您指定其中包含 glob 的模式。传入字段的名称可以与这些模式匹配,以确定它们的类型。
Sunspot 的模式有一些field
内部使用字段的定义,例如 ID 和模型名称。此外,Sunspot 自由地使用dynamicField
定义来建立基于类型的命名约定。
这种字段命名约定的使用允许 Sunspot 定义一个配置 DSL,该 DSL 创建从您的模型到准备被 Solr 索引的 XML 文档的映射。
例如,模型中的这个简单配置块……</p>
searchable do
text :body
end
…将被太阳黑子用来创建一个字段名body_text
. 此字段名称与*_text
模式中以下dynamicField
定义的模式匹配:
<dynamicField name="*_text" type="text" indexed="true" stored="false" multiValued="true"/>
这会将带有后缀的任何字段映射_text
到 Sunspot 的text
类型定义。如果您查看 Sunspot 的 schema.xml,您会看到许多其他类型和选项的类似约定。:stored => true
例如,该选项通常会s
在该类型的后缀上添加一个(例如,_texts
)。
根据我对客户和我自己的项目的经验,有两个很好的案例可以修改 Sunspot 的模式。text
首先,根据您的应用程序可能需要的不同功能对字段分析器进行更改。其次,用于创建全新的类型(通常基于文本类型),以实现更细粒度的 Solr 分析器应用程序。
例如,使用“模糊”搜索扩大搜索匹配可以通过匹配一个特殊的基于文本的字段来完成,该字段也使用语言词干或 NGrams。原始text
字段中的标记可用于填充拼写检查或增强精确匹配。当更严格的匹配失败时,自定义text_ngram
或标记中的标记text_en
可以用于扩大搜索结果。
Sunspot 的 DSL 提供了最后一项功能,用于将您的字段映射到这些自定义字段。一旦你设置了type
它及其对应dynamicField
的定义,你就可以使用 Sunspot 的:as
选项来覆盖基于约定的名称生成。
例如,ngram
为上面添加一个自定义类型,我们最终可能会使用 NGrams 使用以下 Ruby 代码再次处理主体:
searchable do
text :body
text :body_ngram, :as => 'body_ngram'
end
Sunspot 附带了一个针对 sunspot 集成进行了一些调整的库存模式,该集成遵循开发人员最不意外的原则 - 例如,库存 solrconfig.xml 设置为关闭自动提交,即使在生产中您想要打开这个。模式实际上与类型有关,而不是与字段有关——请参阅下面的链接以获取有关如何创建新字段类型的示例。如果字段适合现有类型之一,则索引字段是微不足道的。例如:
class Blog
searchable do
text :title
end
end
在搜索过程中,你会做这样的事情:
class BlogSearch
def self.search(options={})
Sunspot.search(Blog) do
with(:title, options[:title]) if options[:title].present?
end
end
end
Sunspot 的 wiki 有很多额外的文档。这是添加自定义类型以允许 ngram 搜索的示例:
https://github.com/outoftime/sunspot/wiki/Wildcard-searching-with-ngrams