SOLR 不搜索某些字段
Posted
技术标签:
【中文标题】SOLR 不搜索某些字段【英文标题】:SOLR not searching on certain fields 【发布时间】:2010-12-15 08:23:47 【问题描述】:刚刚安装了 Solr,编辑了 schema.xml
,现在正在尝试对其进行索引并使用一些测试数据对其进行搜索。
在我发送给 Solr 的 XML 文件中,我的一个字段如下所示:
<field name="PageContent"><![CDATA[<p>some text in a paragrah tag</p>]]></field>
那里有 html,所以我将它包装在 CDATA 中。
在我的 Solr schema.xml
中,该字段的定义如下所示:
<field name="PageContent" type="text" indexed="true" stored="true"/>
当我运行 POSTing 工具时,一切正常,但是当我搜索我知道在 PageContent
字段中的内容时,我没有得到任何结果。
但是,当我将 <defaultSearchField>
节点设置为 PageContent
时,它可以工作。但如果我将其设置为任何其他字段,它不会在 PageContent
中搜索。
我做错了吗?有什么问题?
澄清错误:
我上传了一个包含以下数据的“文档”:
<field name="PageID">928</field>
<field name="PageName">some name</field>
<field name="PageContent"><![CDATA[<p>html content</p>]]></field>
在我的架构中,我已将字段定义为:
<field name="PageID" type="integer" indexed="true" stored="true" required="true"/>
<field name="PageName" type="text" indexed="true" stored="true"/>
<field name="PageContent" type="text" indexed="true" stored="true"/>
还有:
<uniqueKey>PageID</uniqueKey>
<defaultSearchField>PageName</defaultSearchField>
现在,当我使用 Solr 管理工具并搜索“some name
”时,我得到了一个结果。但是,如果我搜索“html content
”、“html
”、“content
”或“928
”,我没有得到任何结果
为什么?
【问题讨论】:
【参考方案1】:您提到您的默认搜索字段设置为 PageName,我不希望搜索“内容”返回任何内容。
您可能打算将“PageContent:content”放在搜索框中以查找该字段中的数据。如果您想搜索多个字段,您需要查看http://wiki.apache.org/solr/DisMaxRequestHandler。 solr 管理控制台并不是一个很好的工具来玩所有的 DisMax 搜索选项,你只需要操纵 URL。
无论如何,我同意之前的发帖者,如果您的分析设置没有正确设置以处理 HTML,您可能会得到各种意外的搜索结果。去除 HTML 并仅索引文本。
如果您希望标准查询处理程序搜索所有字段,您可以在 solrconfig.xml 中更改它(我总是添加第二个查询处理程序而不是修改“标准”。qf 字段是您想要的字段列表搜索。它是一个空格分隔的列表。
<requestHandler name="standard" class="solr.DisMaxRequestHandler">
<lst name="defaults">
<str name="echoParams">all</str>
<str name="hl">true</str>
<str name="fl">*</str>
<str name="qf">PageName PageContent</str>
</lst>
</requestHandler>
【讨论】:
酷,谢谢特雷。所以让我直截了当。我有点困惑。所以,如果我只是发送一个搜索查询,即“solr/?q=hi i live in the content node” SOLR 只会对单个字段进行查找?当我运行示例香草 SOLR 设置时,我觉得一个简单的查询搜索所有字段?我错了吗? 因为cmets中没有语法高亮,所以我在上面用一个建议澄清了。 如下所述 fl 是返回 NOT 搜索的字段列表。 CommonQueryParameters wiki.apache.org/solr/DisMax - 他们说标准的 solr 查询解析器是愚蠢的,而 dismax 是首选 :) 开源项目通常有不好的默认值... 无论出于何种原因,在 qf 字段中显式添加字段允许我进行搜索(当然是在重新导入之后)。所以谢谢你。我很惊讶他们没有在这些字段上进行搜索,因为我将indexed
属性标记为 TRUE,并且据我所知,我没有指定默认搜索字段。【参考方案2】:
参数fl
不指定要查询的字段,而是指定要在响应中返回的字段。
你可以添加到schema.xml
:
<field name="fieldContainingEverything" type="text" indexed="true" stored="true" multiValued="true" />
<defaultSearchField>fieldContainingEverything</defaultSearchField>
<copyField source="*" dest="fieldContainingEverything" maxChars="3000"/>
现在索引时,每个字段都复制到fieldContainingEverything
。 这里的问题是,如果您想使用该信息进一步评估,您会忘记内容来自的字段。如果有人对此有想法,我会很高兴。
我找到了一个有点实用的解决方案:
更详细地描述该场景:我有一个 mysql 数据库表,其中包含许多要索引的字段,并且只需导入每个字段而不指定每个字段 (SELECT * FROM
...)。我想针对表的每个字段查询索引,并想知道哪个字段与查询匹配。这是不可能的,因为荧光笔只是告诉您匹配查询的字段是fieldContainingEverything
。通过使用 dismax 查询处理程序,我发现即使据说它在每个字段中搜索,我似乎也没有让它搜索 qf
参数中未指定的字段。现在的想法是通过添加以下内容来额外索引每个字段:
<dynamicField name="*" type="string" indexed="true" stored="true"/>
到您的schema.xml
。现在,当您通过 dismax 使用 hl.true&hl.fl=*
查询 Solr 时,您将 qf=fieldContainingEverything^1
添加到您的参数列表中。 Solr 现在搜索每个索引字段,但也会突出显示包含查询词的每个字段。这种方法的缺点显然是增加了索引大小,在我认为的大多数情况下,这不应该是相关的。
【讨论】:
【参考方案3】:fl
是查询返回的字段列表。qf
是您要引用的列表,它不支持通配符..
在不登记所有字段的情况下搜索所有字段的唯一方法是拥有一个捕获所有值(不存储只是索引)的 copyField,然后通过搜索来模拟对所有字段的搜索
【讨论】:
【参考方案4】:在我的 schema.xml 中,我有如下内容,它将每个以 _t 结尾的字段的值复制到文本字段中。
<defaultSearchField>text</defaultSearchField>
<copyField source="*_t" dest="text" maxChars="3000"/>
【讨论】:
【参考方案5】:在尝试搜索数据之前,您要确保数据已提交,对吗?
此外,如果您想存储原始 HTML,最好实际删除 HTML。您可以在您的应用程序中执行此操作,也可以使用 Solr 的 solr.HTMLStripWhitespaceTokenizerFactory,例如:
<tokenizer class="solr.HTMLStripWhitespaceTokenizerFactory"/>
您在“文本”的字段类型定义中声明的内容。您可能想为您的 html 创建一个新的字段类型,可能类似于 text_html,您可以像这样使用它:
<fieldtype name="text_html" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.HTMLStripWhitespaceTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true"/>
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.EnglishPorterFilterFactory" protected="protwords.txt"/>
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.HTMLStripWhitespaceTokenizerFactory"/>
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
<filter class="solr.StopFilterFactory" ignoreCase="true"/>
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.EnglishPorterFilterFactory" protected="protwords.txt"/>
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
</analyzer>
</fieldtype>
我不确定你的意思:
但是,当我将节点设置为 页面内容,它有效。但如果我设置它 到任何其他领域,它不会搜索 在页面内容中。
你能详细说明一下吗?
【讨论】:
cool cody,上面的代码真的很有用,我一定会去掉html。至于 PageContent 问题,我已经在上面更新了我的问题。非常感谢。以上是关于SOLR 不搜索某些字段的主要内容,如果未能解决你的问题,请参考以下文章