假设我有两种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>
然而,我遇到两个问题:
/xml/b[aKey=${a.num}]/value
之类的替换,还是使用aKey
的硬编码值。我的问题是:如何根据上面列出的问题,使用DataImportHandler 正确有效地索引数据?
我正在使用Solr 3.6.2。
注意:这有点类似于this question,但它处理两种XML文档类型而不是RDBMS和XML文档。
答案 0 :(得分:2)
对于那种数据,我使用DataImportHandler的经历非常糟糕。用于合并数据的简单python脚本可能比您当前的配置小,而且更具可读性。根据您的要求和数据大小,您可以创建临时xml文件,也可以直接将结果传递给SOLR。如果您真的必须使用DataImportHandler,则可以使用URLDataSource并设置生成xml的最小服务器。 Obvioulsy我是Python粉丝,但很可能它在Ruby,Perl中也很容易......
答案 1 :(得分:0)
由于我最初未提及的额外设计要求,我终于选择了其他解决方案。以下是解释和讨论。所以....
然后最好与Achim's answer一起开发自己的导入器 - 正如Achim建议的那样,使用您最喜欢的脚本语言,或者使用 SolrJ的进行Java编写
ConcurrentUpdateSolrServer
。
这是因为一旦您需要定义更复杂的导入流,DataImportHandler框架的学习曲线就会突然出现峰值。
然后我建议你考虑使用DataImportHandler,因为你可能最终会实现类似的东西。而且,由于框架非常模块化且可扩展,因此定制不是问题。
这是我提到的额外要求,所以最后我选择了这条路线。
我如何解决了我的特殊困境,即将我需要引用的文件编入索引到单独的内核并使用修改后的SolrEntityProcessor
来访问该数据。修改如下:
如果你不想为每个文件创建一个新的核心,另一种方法是扩展Achim的想法,即创建一个自定义EntityProcessor
,它将预加载数据并以某种方式启用查询。