簡體   English   中英

SOLR中的FullText基於特定字段的子字符串

[英]FullText in SOLR based on substring of specific field

我在我正在研究的項目中使用Apache Solr。 我已經完成所有設置,而且還可以執行SOLR查詢。 但是-我對SOLR的一種行為感到困惑-即使在論壇上搜索后-也無法理解這種行為。

在我的solr模式中,我有一個類型為solr.TextField field 我正在嘗試對其進行fullTextSearch。 僅當我在搜索關鍵字之前和之后都包含通配符* ,查詢才會向我返回結果。 如果僅在末尾添加它,則它不起作用(例如: searchWord*

但是,許多在線論壇提到solr / lucene在搜索詞開頭不支持*

請在以下schema.xml找到。 注意:我正在使用solr v 7.4.0

<?xml version="1.0" encoding="utf-8" ?>

<schema name="blog_schema" version="1.4">

  <types>
    <fieldType name="string" class="solr.StrField" />
    <fieldType name="text" class="solr.TextField" />
    <fieldType name="long" class="org.apache.solr.schema.LongPointField" docValues="true" />
    <fieldType name="date" class="org.apache.solr.schema.DatePointField"  docValues="true" sortMissingLast="true" omitNorms="true"/>
  </types>

  <fields>
    <field name="post_id" type="string" indexed="true" stored="true" required="true" />
    <field name="title" type="string" indexed="true" stored="true" required="true" />
    <field name="author" type="string" indexed="true" stored="true" required="true" />
    <field name="corpus" type="text" indexed="true" stored="true" required="false"  />
    <field name="fullText" type="text" indexed="true" multiValued="true" />
    <copyField source="*"  dest="fullText" />
  </fields>

  <uniqueKey>post_id</uniqueKey>


</schema>

您可以看到我已經定義了corpusfullText字段為solr.TextField類型。 這兩個字段都有大量的文本數據。

我打算對corpusfullText字段進行全文搜索。 為此,我使用SOLR查詢,如下所示: corpus:*Thermodynamics*

上面的查詢使用通配符,它​​確實起作用並返回我預期的結果。 但是我不知道這是否是正確的方法。 許多論壇上提到, *在搜索查詢的開始是不支持的。 另一個觀察結果是:如果我只使用語料庫中的第一個單詞並使用corpus: Thermodynamics*搜索corpus: Thermodynamics* -它確實起作用。 但是,這不適用於語料庫后面出現的單詞(即,不是語料庫中第一個單詞的所有單詞)

我的印象是SOLR理解空格/換行符將被忽略。 可以這么說,語料庫上有文字: Physics has a specialization for Thermodynamics and Heat 然后,SOLR查詢corpus: Thermodynamics*corpus: Thermodynamics應該起作用,因為Thermodynamics本身就是一個詞,SOLR會理解忽略空白應該被忽略。 相反,我必須在搜索字詞的開頭和結尾都包含通配符*

請幫我解釋一下
1.為什么這樣的行為如此,盡管論壇聲稱SOLR不支持搜索詞開頭的*
2.我在corpus字段上執行fullText的方式是否正確?

謝謝,車丹

這里有很多事情在起作用,所以讓我們從字段類型開始:

<fieldType name="text" class="solr.TextField" />

..這實際上並沒有定義有用的字段類型。 為此,您需要附加一個分詞器和幾個過濾器。 令牌生成器將文本拆分為令牌,而令牌則產生匹配。 這稱為分析鏈。

<fieldType name="text" class="solr.TextField">
  <analyzer>
    <tokenizer class="solr.WhitespaceTokenizerFactory" />
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

Whitespace令牌生成器會將“ foo bar baz”分為三個令牌foobarbaz 任何查詢都將執行相同的操作,並將令牌與令牌匹配。 這就是為什么您將獲得匹配項的原因,即使搜索是bar baz foo而不是與之前的序列也不相同。 通常,您通常還希望至少附加一個LowercaseFilter ,以便進行不區分大小寫的搜索-以及其他過濾器,具體取決於您的字段和域的用例。 創建多個字段以執行不同的匹配,然后分別對它們進行加權,以獲得對您的用戶最有意義的文檔評分。

沒有這個分析鏈,我相信您實際上將獲得與字符串字段相同的行為。

然后是通配符-如果存在通配符,則會跳過整個分析鏈。 這意味着在文本搜索時使用通配符通常是一個壞主意。 除非您嘗試匹配單個令牌,否則它不會做您想做的事情(因為存在通配符時將跳過令牌生成器)。 因此,您必須格外小心,並且您很可能最終會遇到“為什么會這樣”的情況。

另一種選擇是使用NGramFilter,它將單詞中的每個字母集( foo變成ffofoooooo )分成單獨的標記。 通常,您只希望在建立索引時執行此操作,因此請為您的字段使用單獨的分析鏈(您可以通過配置中的type參數定義此分析鏈-如果未指定任何類型,則將使用同一鏈進行索引和查詢。

建議使用前綴通配符( *foo )的原因是,與檢查后綴通配符( foo* )相比,檢查前綴通配符的開銷很大。 在后綴的情況下,您可以僅從foo遍歷索引,並繼續進行直到遇到不是以foo開頭的內容,而對於*foo您必須有效地查看索引中的所有術語,因為沒有排序保持相反順序的順序。

輸入反向通配符過濾器 -該過濾器的作用是,除了常規標記外,它還為反向標記(或僅反向標記)建立索引。 然后在查詢時調用過濾器,並反轉查詢令牌-有效索引oof ,然后在內部查詢oof* 這樣,您就可以加快保持對該字段排序的索引的速度,而不必查看每個標記。

該過濾器反轉令牌以提供更快的前導通配符和前綴查詢。 沒有通配符的令牌不會被反轉。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM