使用solrcell和tika索引丰富的文档

时间:2017-05-18 09:58:27

标签: indexing solr apache-tika cloudera-manager

我是Solr搜索的新手,目前正在努力让Solr Cell与Tika合作。请考虑以下文本文件:

Name:                    Popeye
Nationality:             American

我希望Solr能给我两个名为' name'和国民'与诗歌和美国的价值观。为此,我将schema.xml文件中的两个字段定义为

   <field name="name" type="text_general" indexed="true" stored="true"/>
   <field name="nationality" type="text_general" indexed="true" stored="true"/>

text_general字段定义为

<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
  <analyzer type="index">
    <tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
    <!-- in this example, we will only use synonyms at query time
                 <filter class="solr.SynonymFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/>
    -->
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
    <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

在solrconfig.xml文件中,我定义了更新/提取方法

<requestHandler name="/update/extract" class="solr.extraction.ExtractingRequestHandler" >
    <lst name="defaults">
    <str name="lowernames">true</str>
    <str name="uprefix">attr_</str>
    <str name="captureAttr">true</str>

最后,我运行命令将文档索引为

curl 'http://localhost:8983/solr/popeye_bio_collection_shard1_replica1/update/extract?literal.id=doc1&commit=true' -F "myfile=@/tmp/popeye_bio.txt"

文档被编入索引而没有错误。当我使用查询命令

curl 'http://localhost:8983/solr/popeye_bio_collection_shard1_replica1/select?q=*%3A*&wt=json&indent=true'

我得到输出为

    {
    "responseHeader":{
    "status":0,
    "QTime":3,
    "params":{
      "indent":"true",
      "q":"*:*",
      "wt":"json"}},
      "response":{"numFound":1,"start":0,"docs":[
      {
        "attr_meta":["stream_source_info",
          "myfile",
          "stream_content_type",
          "text/plain",
          "stream_size",
          "206",
          "Content-Encoding",
          "windows-1252",
          "stream_name",
          "popeye_bio.txt",
          "Content-Type",
          "text/plain; charset=windows-1252"],
        "id":"doc1",
        "attr_stream_source_info":["myfile"],
        "attr_stream_content_type":["text/plain"],
        "attr_stream_size":["206"],
        "attr_content_encoding":["windows-1252"],
        "attr_stream_name":["popeye_bio.txt"],
        "attr_content_type":["text/plain; charset=windows-1252"],
        "attr_content":[" \n \n  \n  \n  \n  \n  \n  \n  \n \n  Name:                    Popeye\r\nNationality:             American\r\n \n  "],
        "_version_":1567726521681969152}]
  }}

正如您所看到的,popeye和american在我在schema.xml文件中定义的字段中没有编入索引。我在这做错了什么?我尝试将标记生成器更改为text_general字段类型为<tokenizer class="solr.PatternTokenizerFactory" pattern=": "/>。但它没有任何区别。在这方面,我将不胜感激!

2 个答案:

答案 0 :(得分:0)

当您定义一个标记生成器时,您只是向Solr指示 all 该字段中发送的数据应该使用您的配置进行标记/处理,但最后,您&# 39;重新将所有信息发送到一个字段。

Solr假设您的数据是结构化的(1个包含字段的文档)。因此,一个分析器/标记器无法创建更多字段。分析器/标记器的功能基本上只是标记和转换进入倒排索引的文本进行搜索。

你可以做的是使用ScriptUpdateProcessor并定义一个管道来进行修改(将一个字段分成几个),然后再将文本放入标记器。类似的东西:

<processor class="solr.StatelessScriptUpdateProcessorFactory">
    <str name="script">splitField.js</str>
</processor>

splitField.js文件可能包含:

function processAdd(cmd) {
    doc = cmd.solrDoc;  // org.apache.solr.common.SolrInputDocument
    field = doc.getFieldValue("attr_content");

    // split your attr_content text into two variables:
    // name and nationality, then

    doc.setField("name", name);
    doc.setField("nationality", nationality);
}

在一个理想的世界中,这应该在Solr之外处理,但是使用ScriptUpdateProcessor,你可以完成你想要的任务。

答案 1 :(得分:0)

我目前的做法是在更新/提取方法中定义'update.chain'

<requestHandler name="/update/extract" class="solr.extraction.ExtractingRequestHandler" >
    <lst name="defaults">
<str name="update.chain">mychain</str>
    <str name="lowernames">true</str>
    <str name="uprefix">attr_</str>
    <str name="captureAttr">true</str>

其中mychain

<updateRequestProcessorChain name="mychain">
     <processor class="solr.StatelessScriptUpdateProcessorFactory">
            <str name="script">splitField.js</str>
     </processor>
  <processor class="solr.LogUpdateProcessorFactory" />
  <processor class="solr.RunUpdateProcessorFactory" />
</updateRequestProcessorChain>

我将它包含在update / extract方法中,以便调用处理器。如果我理解正确,我应该在update/extract方法之后和文本发送到tokenizer之前调用处理器。如果是这样,那么如何调用处理器呢?

我还尝试从<str name="update.chain">mychain</str>删除update/extract行,然后调用

curl 'http://localhost:8983/solr/popeye_bio_collection_shard1_replica1/update/extract?literal.id=doc1&update.chain=mychain&commit=true' -F "myfile=@/tmp/popeye_bio.txt"

我得到了同样的错误。 splitFiled.js定义为

function processAdd(cmd) {
doc = cmd.solrDoc; // org.apache.solr.common.SolrInputDocument
field = doc.getFieldValue("attr_content");
// split your attr_content text into two variables:
// name and nationality, then
doc.setField("name", name);
doc.setField("nationality", nationality);
}

function processDelete(cmd) {
}

function processMergeIndexes(cmd) {
}

function processCommit(cmd) {
}

function processRollback(cmd) {
}

function finish() {
}

错误发生在setField行。有什么方法可以在控制台中打印'field'吗?也许,'console.log'方法?

相关问题