Solr DataImportHandler - 索引多个相关的XML文档

时间:2013-05-08 16:43:23

标签: solr

假设我有两种XML文档类型,A和B,如下所示:

<xml>
    <a>
        <name>First Number</name>
        <num>1</num>
    </a>
    <a>
        <name>Second Number</name>
        <num>2</num>
    </a>
</xml>

B:

<xml>
    <b>
        <aKey>1</aKey>
        <value>one</value>
    </b>
    <b>
        <aKey>2</aKey>
        <value>two</value>
    </b>
</xml>

我想像这样索引:

<doc>
    <str name="name">First Name</str>
    <int name="num">1</int>
    <str name="spoken">one</str>
</doc>
<doc>
    <str name="name">Second Name</str>
    <int name="num">2</int>
    <str name="spoken">two</str>
</doc>

所以,实际上,我正在尝试使用A中的值作为B中的键。使用DataImportHandler,我使用以下作为我的数据配置定义:

<dataConfig>
    <dataSource type="FileDataSource" encoding="UTF-8" />
    <document>
        <entity name="document" transformer="LogTransformer" logLevel="trace"
            processor="FileListEntityProcessor" baseDir="/tmp/somedir"
            fileName="A.*.xml$" recursive="false" rootEntity="false"
            dataSource="null">
            <entity name="a"
                transformer="RegexTransformer,TemplateTransformer,LogTransformer"
                logLevel="trace" processor="XPathEntityProcessor" url="${document.fileAbsolutePath}"
                stream="true" rootEntity="true" forEach="/xml/a">
                <field column="name" xpath="/xml/a/name" />
                <field column="num" xpath="/xml/a/num" />


                <entity name="b" transformer="LogTransformer"
                    processor="XPathEntityProcessor" url="/tmp/somedir/b.xml"
                    stream="false" forEach="/xml/b" logLevel="trace">
                    <field column="spoken" xpath="/xml/b/value[../aKey=${a.num}]" />
                </entity>

            </entity>
        </entity>
    </document>
</dataConfig>

然而,我遇到两个问题:

  1. 我无法使用谓词来获取XPath表达式以匹配任何行;无论我是使用/xml/b[aKey=${a.num}]/value之类的替换,还是使用aKey的硬编码值。
  2. 即使我删除了谓词,解析器也会为A中的每一行检查一次B文件,这显然效率低下。
  3. 我的问题是:如何根据上面列出的问题,使用DataImportHandler 正确有效地索引数据?

    我正在使用Solr 3.6.2。

    注意:这有点类似于this question,但它处理两种XML文档类型而不是RDBMS和XML文档。

2 个答案:

答案 0 :(得分:2)

对于那种数据,我使用DataImportHandler的经历非常糟糕。用于合并数据的简单python脚本可能比您当前的配置小,而且更具可读性。根据您的要求和数据大小,您可以创建临时xml文件,也可以直接将结果传递给SOLR。如果您真的必须使用DataImportHandler,则可以使用URLDataSource并设置生成xml的最小服务器。 Obvioulsy我是Python粉丝,但很可能它在Ruby,Perl中也很容易......

答案 1 :(得分:0)

由于我最初未提及的额外设计要求,我终于选择了其他解决方案。以下是解释和讨论。所以....

如果您的Solr实例只有一个或几个导入流类型:

然后最好与Achim's answer一起开发自己的导入器 - 正如Achim建议的那样,使用您最喜欢的脚本语言,或者使用 SolrJ的进行Java编写  ConcurrentUpdateSolrServer

这是因为一旦您需要定义更复杂的导入流,DataImportHandler框架的学习曲线就会突然出现峰值。

如果您有非常多的不同导入流程:

然后我建议你考虑使用DataImportHandler,因为你可能最终会实现类似的东西。而且,由于框架非常模块化且可扩展,因此定制不是问题。

这是我提到的额外要求,所以最后我选择了这条路线。

我如何解决了我的特殊困境,即将我需要引用的文件编入索引到单独的内核并使用修改后的SolrEntityProcessor来访问该数据。修改如下:

  • 应用sub-entity problem
  • 的补丁
  • 添加缓存(使用Guava的快速解决方案,可能有更好的方法使用可用的Solr API在本地访问其他核心,但在那时我有点匆忙)。

如果你不想为每个文件创建一个新的核心,另一种方法是扩展Achim的想法,即创建一个自定义EntityProcessor,它将预加载数据并以某种方式启用查询。