SOLR无法搜索某些字段

6

我刚安装了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"/>

当我运行POST工具时,一切都很顺利,但是当我搜索我知道在PageContent字段中的内容时,我没有得到任何结果。
然而,当我将<defaultSearchField>节点设置为PageContent时,它可以正常工作。但如果我将其设置为任何其他字段,则不会搜索PageContent
我做错了什么吗?问题出在哪里?
为了澄清错误:
我上传了一个包含以下数据的“doc”:
<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管理工具搜索“某个名称”时,我会得到结果。但是,如果我搜索“html内容”,“html”,“内容”或“928”,我就找不到结果了。
为什么呢?
5个回答

7

您提到默认搜索字段设置为PageName,因此我不会期望搜索“content”会返回任何结果。

您可能想在搜索框中输入“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>

很酷,谢谢Trey。让我来搞清楚一下。我有点困惑。所以,如果我只发送一个搜索查询,比如“solr/?q=hi i live in the content node”,SOLR只会针对单个字段进行查找吗?当我运行示例vanilla SOLR设置时,我感觉一个简单的查询可以搜索所有字段?我错了吗? - andy
1
因为注释中没有语法高亮显示,所以我在上面进行了澄清并提出了建议。 - Trey
如下所述,fl 是要返回的字段列表,而不是要进行搜索的字段。CommonQueryParameters - drfence
http://wiki.apache.org/solr/DisMax - 他们说标准的Solr查询解析器很愚蠢,而Dismax则是更好的选择 :) 开源项目通常有糟糕的默认设置... - axk
不知何故,在qf字段中明确添加字段后,我可以进行搜索(当然需要重新导入)。所以感谢你。我很惊讶他们没有在这些字段上进行搜索,因为我将“indexed”属性标记为TRUE,据我所知,我没有指定默认搜索字段。 - The Unknown Dev

1

在尝试搜索数据之前,您要确保已提交数据,对吧?

另外,如果您想存储原始HTML,最好实际上删除HTML。您可以在应用程序中或使用Solr的solr.HTMLStripWhitespaceTokenizerFactory进行此操作,例如:

<tokenizer class="solr.HTMLStripWhitespaceTokenizerFactory"/> 

在“text”的字段类型定义中声明。您可能想为您的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> 

我不确定您的意思是什么:

然而,当我将节点设置为PageContent时,它可以工作。但如果我将其设置为其他任何字段,则不会在PageContent中搜索。

您能否详细说明一下?


酷酷的 Cody,上面的代码确实很有用,我一定会剥离 HTML。至于 PageContent 的问题,我已经在上面更新了我的问题。非常感谢。 - andy

1

fl 是查询返回的字段列表。 qf 是您想要引用的列表,它不支持通配符。

在不列出所有字段的情况下搜索所有字段的唯一方法是拥有一个捕获所有值(仅索引而非存储)的 copyField,然后通过针对它进行搜索来模拟针对所有字段进行搜索。


0

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 查询 Solr 时,使用参数列表添加 hl.true&hl.fl=*,并且添加 qf=fieldContainingEverything^1。Solr 现在会搜索每个索引字段,并突出显示包含查询词的每个字段。显然,这种方法的缺点是增加了索引大小,在大多数情况下应该不太相关。


0
在我的 schema.xml 文件中,我有以下类似的内容,它将每个以 _t 结尾的字段的值复制到文本字段中。
<defaultSearchField>text</defaultSearchField>
<copyField source="*_t" dest="text" maxChars="3000"/>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接