Apache Solr的配置備忘錄

首先

因为似乎需要对DB(PostgreSQL)进行全文搜索,所以这是我在调研时做的笔记。(虽然感觉被Elasticsearch所推崇,但这次先用这个…)
整体上我参考了这篇博客。(尽管讲解的版本有点旧…)
如果你擅长英语,那就参考文档是最好的选择,但我不擅长…(偶尔会参考一些地方)

环境

    • Apache Solr 7.3.1

 

    PostgreSQL 10.4

准备好的事项

在解释之前,我们假设以下两点已经完成。

    • Solorのインストール

 

    PostgreSQLのインストール

※ 我在Solr中创建了一个名为“test”的核心。

与PostgreSQL的连接设置

    Solrの動作設定ファイル(solrconfig.xml)
  <lib dir="${solr.install.dir:../../../..}/server/lib/" regex="postgresql-\d.*\.jar" />
  <lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-dataimporthandler-\d.*\.jar" />
  <lib dir="${solr.install.dir:../../../..}/contrib/dataimporthandler-extras/lib/" regex=".*\.jar" />

当在dir中指定路径时,将添加指定目录下的所有jar文件。此外,通过在regex中使用正则表达式指定文件名,可以将添加的目标限定为与指定的正则表达式匹配的文件。

这次添加的内容包括用于PostgreSQL连接的jar文件和用于数据导入的jar文件。

    <requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
        <lst name="defaults">
          <str name="config">data-config.xml</str>
        </lst>
    </requestHandler>

在这里,我们将提供用于DataImport的基本设置。详细的设置内容将在DataConfig文件中进行说明。
要使用的DataConfig文件是通过进行设置的。这次我们使用了名为data-config.xml的文件。(关于DataConfig文件的详细信息将在后面提到。)
此外,我们需要提前下载适当版本的PostgreSQL用的JDBC。

    <schemaFactory class="ClassicIndexSchemaFactory"/>

由于我们将使用schema.xml来定义模式,因此需要进行以上配置。

  <updateProcessor class="solr.AddSchemaFieldsUpdateProcessorFactory" name="add-schema-fields">
    <lst name="typeMapping">
      <str name="valueClass">java.lang.String</str>
      <str name="fieldType">text_general</str>
      <lst name="copyField">
        <str name="dest">*_str</str>
        <int name="maxChars">256</int>
      </lst>
      <!-- Use as default mapping instead of defaultFieldType -->
      <bool name="default">true</bool>
    </lst>

        ~(略)~

    <lst name="typeMapping">
      <str name="valueClass">java.lang.Number</str>
      <str name="fieldType">pdoubles</str>
    </lst>
  </updateProcessor>

默认情况下应该已经设置了上述设置,但如果使用schema.xml,则不需要,所以要删除它。(请注意,在注释时不要嵌套以防止出现错误)

  <updateRequestProcessorChain name="add-unknown-fields-to-the-schema" default="${update.autoCreateFields:true}"
           processor="uuid,remove-blank,field-name-mutating,parse-boolean,parse-long,parse-double,parse-date,add-schema-fields">
    <processor class="solr.LogUpdateProcessorFactory"/>
    <processor class="solr.DistributedUpdateProcessorFactory"/>
    <processor class="solr.RunUpdateProcessorFactory"/>
  </updateRequestProcessorChain>

从上述processor的设置中删除add-schema-fields。

    データ検索のスキーマ定義ファイル(schema.xml)
  <field name="name" type="text_en" termPositions="true" termVectors="true" indexed="true" stored="true"/>
  <field name="body" type="text_en" termPositions="true" termVectors="true" indexed="true" stored="true"/>
  <field name="updated" type="pdate" termPositions="true" termVectors="true" indexed="true" stored="true"/>

将已存在于数据导入目标表中的列添加。
名称:字段名
类型:设定为fieldType的类型
termPositions:是否返回包含搜索关键词的位置
termVectors:是否包含搜索关键词的数量、关键词的起始和结束位置等结果
indexed:是否添加索引
stored:是否将字段包含在搜索结果中

    DBを検索対象にする場合のデータ構造定義ファイル
<dataConfig>
  <dataSource driver="org.postgresql.Driver" url="jdbc:postgresql://localhost:5432/postgres" user="postgres" />
  <document>
      <entity name="test" query="select * from test"
              deltaQuery="select id from test where updated >= '${dataimporter.last_index_time}'"
              deltaImportQuery="select * from test where id=${dataimporter.delta.id}">
        <field column="id" name="id" />
        <field column="name" name="name" />
        <field column="body" name="body" />
        <field column="update" name="updated" />
      </entity>
  </document>
</dataConfig>

数据源:设置数据源配置
驱动程序:设置要使用的驱动程序的名称。这次是为了连接到PostgreSQL,所以设置为org.postgresql.Driver。
URL:设置连接的目标URL。这次指定了事先创建的PostgreSQL数据库。
用户:设置连接目标时使用的用户名。
密码:设置连接目标时使用的密码。这次我们没有设置,因为我们在PostgreSQL的密码设置中将其关闭了。
文档:
实体:设置要获取的数据
名称:实体的名称
查询:获取所有数据的SQL
增量查询:获取数据库中所有数据和Solr已获取的数据之间的差异的SQL
增量导入查询:用于导入数据的SQL。这次只获取通过增量查询获取的ID数据的SQL。
字段:设置数据字段
列:数据库的列名
名称:获取后的字段名

※补充说明
从维基百科获取数据

<dataConfig>
  <dataSource driver="org.postgresql.Driver"
              url="jdbc:postgresql://localhost:5432/wikipedia"
              user="wikipedia"
              password="secret" />
  <document>
    <entity name="page" query="SELECT page_id, page_title from page">
      <field column="page_id" name="id" />
      <field column="page_title" name="name" />
      <entity name="revision" query="select rev_id from revision where rev_page=${page.page_id}">
        <entity name="pagecontent" query="select old_text from pagecontent where old_id=${revision.rev_id}">
          <field column="old_text" name="text" />
        </entity>
      </entity>
    </entity>
  </document>
</dataConfig>

这是一篇旧的文章,但是有关Apache Solr的schema.xml的详细解读,请参考。

搜索设置

在Solr的分词器中有各种可用的过滤器。

字符过滤器

charFilter是在字符串解析之前对数据进行处理的组件。(它可以将不必要或需要替换的内容排除在搜索的数据中)

    マッピング用の定義ファイルを使用
<charFilter class="solr.MappingCharFilterFactory" mapping="[定義ファイルパス]"/>
 "0" => "0"
 "1" => "1"
 "2" => "2"
 "3" => "3"
 "4" => "4"
 "5" => "5"
 "6" => "6"
 "7" => "7"
 "8" => "8"
 "9" => "9"

进行如上所述的设置,可以将全角数字转换为半角数字。

分词器

我们将进行关于搜索关键词拆分的解析方法的设置。

似乎以下两个选项经常被使用。

    形態素解析による文字列分割

我们将以有意义的语言单位将单词分割开来。

<tokenizer class="solr.JapaneseTokenizerFactory" mode=[検索モード] userDictionary=[ユーザ固有設定の単語登録ファイル]  userDictionaryEncoding=[userDictionaryのエンコード]  discardPunctuation=true />

模式
普通:标准的词分割
搜索:适用于搜索的词分割
扩展:搜索+单字词的词分割
用户词典:用户设置
请参考设置文件样例,位于\example\example-DIH\solr\solr\conf\lang下的「userdict_ja.txt」。

#
# This is a sample user dictionary for Kuromoji (JapaneseTokenizer)
#
# Add entries to this file in order to override the statistical model in terms
# of segmentation, readings and part-of-speech tags.  Notice that entries do
# not have weights since they are always used when found.  This is by-design
# in order to maximize ease-of-use.
#
# Entries are defined using the following CSV format:
#  <text>,<token 1> ... <token n>,<reading 1> ... <reading n>,<part-of-speech tag>
#
# Notice that a single half-width space separates tokens and readings, and
# that the number tokens and readings must match exactly.
#
# Also notice that multiple entries with the same <text> is undefined.
#
# Whitespace only lines are ignored.  Comments are not allowed on entry lines.
#

# Custom segmentation for kanji compounds
日本経済新聞,日本 経済 新聞,ニホン ケイザイ シンブン,カスタム名詞
関西国際空港,関西 国際 空港,カンサイ コクサイ クウコウ,カスタム名詞

# Custom segmentation for compound katakana
トートバッグ,トート バッグ,トート バッグ,かずカナ名詞
ショルダーバッグ,ショルダー バッグ,ショルダー バッグ,かずカナ名詞

# Custom reading for former sumo wrestler
朝青龍,朝青龍,アサショウリュウ,カスタム人名

如果将discardPunctuation设置为false,则会保留句子中的标点符号。如果将其设置为true,则会删除句子中的标点符号(默认为true)。

    N-gram トークナイザ

在指定的字符数间隔上切分单词。常用的方法是将其分成2个字符一组的Bigram。

<tokenizer class="solr.NgramTokenizerFactory" minGramSize="" maxGramSize="" />

minGramSize:最小字符分割数(大于0)
maxGramSize:最大字符分割数(不小于minGramSize)

有人整理了一篇文章,介绍了同时使用上述两种方法进行搜索的方式,请参考以下内容。如何在Solr中实现结合词法解析和Ngram的混合搜索方法。

过滤

这是在Solr中设置字符串检索过滤器。可用的选项取决于上述分词器的设置。

    類語のパターンを登録して検索対象にする
<filter class="solr.SynonymGraphFilterFactory" synonyms="[類語のパターンファイルパス]"/>

将类似词汇模式的路径写入文件中。

couch,sofa,divan
teh => the
huge,ginormous,humungous => large
small => tiny,teeny,weeny
    • ‘,’区切り

 

    •  ’,’で並べている単語をすべて類語として扱います。

 

    • ‘=>’

 

     ’=>’の左側に記載された単語は、右側に記載された単語として扱われます。(左側の単語自体は右の変換対象に含めない限り検索対象になりません。)

忽略大小写:如果为true,则不区分英文字母的大小写来判断同义词。(默认为false)
展开:如果为true,则提取所有的同义词。如果为false,则只提取第一个找到的同义词。(默认为true)
格式:控制同义词的转换格式。
tokenizerFactory:在转换同义词文件时使用的tokenizerFactory的名称。
analyzer:在转换同义词文件时使用的分析器类的名称。

    動詞を基本形にする
<filter class="solr.JapaneseBaseFormFilterFactory"/>
    品詞を除外する
<filter class="solr.JapanesePartOfSpeechStopFilterFactory"  tags="lang/stoptags_ja.txt" enablePositionIncrements="true"/>

标签:设置排除目标列表文件路径。列表文件的示例位于样本文件夹的conf/lang/stoptags_ja.txt。当排除令牌时,如果enablePositionIncrements为false且版本低于4.3,则似乎不会保留过滤位置。据说从5.0版本开始已修复。

    全角⇔半角の処理を行う
<filter class="solr.CJKWidthFilterFactory"/>

将全角英文字转换为半角英文字,将半角片假名转换为全角片假名。全角数字不受影响。(需要先通过MappingCharFilterFactory等方式进行处理)

    • カタカナの長音を取り除く

 

    「コンピューター」と「コンピュータ」など、同じ意味でも長音をつけたりつけなかったりする単語を統一するために設定します。
<filter class="solr.JapaneseKatakanaStemFilterFactory" minimumLength="4"/>

最小长度:如果字符数超过设定值,则会被排除。设定值默认为4,最小值为2。

    • 英字を小文字に変換する

 

    英字をすべて小文字に変換することで表記ゆれを統一します。
<filter class="solr.LowerCaseFilterFactory"/>
    • インデックスさせない単語を登録

 

    「て」「に」「を」「は」や、「によって」「に関して」など検索時に必要ない単語を除外します。
<filter class="solr.StopFilterFactory" words="lang/stopwords_ja.txt"  ignoreCase="true"/>

设置不进行索引的词列表路径。
格式
如果ignoreCase为true,则在判定同义词时不区分英文字母的大小写。(默认为false)
启用位置增量。

提示功能设定

通过启用建议功能,您可以在搜索时显示输入内容的候选项。(有关详细信息,请参阅“おいしい健康様的博客”。)

关于显示为备选语言的数据

请参考以下详细的博客内容,其中提到可以使用”搜寻对象的语素解析”或者”搜寻日志”的方法。请根据系统的需求,从优缺点的角度选择其中之一。

solrconfig.xml的配置

    searchComponentの追加

首先,我们使用solr.SpellCheckComponent类来添加设置。(我认为不一定非得是Solr的)

<searchComponent class="solr.SpellCheckComponent" name="[searchComponentの名称]">
    <lst name="[名称]">
      <str name="name">[searchComponentの名称]</str>
      <str name="classname">org.apache.solr.spelling.suggest.Suggester</str>
      <str name="lookupImpl">org.apache.solr.spelling.suggest.fst.AnalyzingLookupFactory</str>
      <str name="buildOnCommit">true</str>
      <str name="comparatorClass">score</str>
      <str name="field">[検索対象のフィールド名]</str>
      <str name="suggestAnalyzerFieldType">[解析に使用するfieldType名]</str>
      <bool name="exactMatchFirst">true</bool>
    </lst>
    <str name="queryAnalyzerFieldType">[解析に使用するfieldType名]</str>
</searchComponent>
    requestHandlerの追加

为了接收指定路径上的searchComponent定义的内容,我们需要定义一个requestHandler。

<requestHandler name="[パス]" class="org.apache.solr.handler.component.SearchHandler">
    <lst name="defaults">
      <str name="spellcheck">true</str>
      <str name="spellcheck.dictionary">[コンポーネント名]</str>
      <str name="spellcheck.collate">true</str>
      <str name="spellcheck.count">100</str>
      <str name="spellcheck.onlyMorePopular">true</str>
    </lst>
    <arr name="components">
      <str>[コンポーネント名]</str>
    </arr>
</requestHandler>

命令 (Ming4 ling4)

以下是用于从控制台启动和停止Solr等操作的命令,我们这次使用的命令是:

 solr start (-d [サーバディレクトリ名])
 solr stop -all
 solr create -c [コア名]

只是补充一下,我已经将\solr-7.3.1\bin注册到环境变量的Path中了。(因为每次切换目录或者输入路径太麻烦了)

结束时

我第一次调查搜索引擎,发现有很多用于搜索的过滤器,所以似乎可以应对各种情况。但是我也注意到需要小心应用顺序,否则可能会出现意外的过滤效果,这也让它变得相当困难。

此外,除了Apache Solr之外(Elasticsearch也相当受欢迎吧?),还有各种其他搜索引擎,也许应该进行比较,找到易于使用的更好的选择。

如果公式文件是用英语写的,可能会有一些翻译错误的地方,如果是这样的话,请您指出来,我们将不胜感激。

广告
将在 10 秒后关闭
bannerAds