使用 MySQL 作为源的 Solr DataImportHandler - 处理 json 类型的列
Solr DataImportHandler using MySQL as source - dealing with json type columns
我有一个 MySQL 数据库,其中包含从一些爬行过程中收集的数据,现在我想将数据复制到 solr 核心中,为它们提供更好的结构并能够对它们执行特定搜索.
我已经能够在我的核心上使用 DataImportHandler,配置原始数据-config.xml 模式以在单个 table,但在开始处理其他相关实体之前,我必须弄清楚如何解决一个简单的问题。
在我的许多 SQL table 中,我有一些列使用 MySQL 的 JSON 类型存储数据(是的,我应该从一开始就使用了 no-sql)
示例数据
{
"slug": "sample-item-slug",
"Released": "2008",
"Platforms": "Nintendo DS, PSP",
"DevelopedBy": "Sample Developer",
"PublishedBy": "Sample Publisher"
}
我希望能够将 json 对象中的键作为我的 SOLR 文档的字段导入。
如何做到这一点?我看过 Transformers,但似乎没有专门用于此目的的...
有人可以给我一些建议吗?
提前致谢。
我设法解决了我的小问题,解决方案有多种
使用ScriptTransformer
正如@MatsLindh 所说,对于 JSON 列中的字段是动态的情况,最好的方法可能是使用 javascript 函数来转换列数据,将其解析为JSON 字符串并迭代生成的对象以将行添加到列数据。
ScriptTransformer 的示例函数
function splitMetadata(row) {
var metadata;
metadata = JSON.parse(row.get('metadata'));
if (metadata) {
Object.keys(metadata).map(function(key, index) {
row.put(key,metadata[key]);
});
}
return row;
}
正如Solr Docs所说,传递给函数的row
变量是Java Map<String,Object>
类型,因此您可以使用get,put,remove
轻松地向其添加数据。
示例 data-config.xml
使用 ScriptTransformer
根据问题中指定的数据模型,请注意我还使用 RegexTransformer
使用指定的分隔符将字符串拆分为多个值。
<entity name="metadata" query="select metadata from games" transformer="RegexTransformer,script:splitMetada">
<field column="slug" name="attr_platforms" splitBy=" ," />
<field column="Platforms" name="attr_platforms" splitBy=" ," />
<field column="Released" name="release_date_dt" />
<field column="DevelopedBy" name="developer_s" />
<field column="DevelopedBy" name="publisher_s" />
</entity>
使用 MySQL 内联路径运算符 ->>
如果您的列中有固定数量的 json 键,您可以使用 MySQL 的 内联路径运算符 [=56= select 它们], select 在 JSON 列中指定的键,像这样:
样本MySQL查询
基于问题中指定的数据模型
SELECT
metadata->>'$.Released' AS release_date,
metadata->>'$.Platforms' AS platforms,
metadata->>'$.DevelopedBy' AS developer,
metadata->>'$.PublishedBy' AS publisher
FROM games WHERE id='${game.ID}'
作为 ScriptTransformer 解决方案,您可以在 data-config.xml
文件中将 metadata
列(在我的例子中包含 JSON 的列)声明为 <entity>
并且将其作为连接 table 处理,您还可以在数据库上创建 view
以避免在 XML
中编写查询
示例 data-config.xml
使用 MySQL 查询
基于上面指定的查询
<entity name="metadata" query="select metadata->>'$.Released' as release_date,metadata->>'$.Platforms' as platforms,metadata->>'$.DevelopedBy' as developer, metadata->>'$.PublishedBy' as publisher FROM games where id='${game.ID}'">
<field column="release_date" name="release_date_dt" />
<field column="platforms" name="attr_platforms" />
<field column="developer" name="developer_txt" />
<field column="publisher" name="publisher_txt" />
</entity>
我有一个 MySQL 数据库,其中包含从一些爬行过程中收集的数据,现在我想将数据复制到 solr 核心中,为它们提供更好的结构并能够对它们执行特定搜索.
我已经能够在我的核心上使用 DataImportHandler,配置原始数据-config.xml 模式以在单个 table,但在开始处理其他相关实体之前,我必须弄清楚如何解决一个简单的问题。
在我的许多 SQL table 中,我有一些列使用 MySQL 的 JSON 类型存储数据(是的,我应该从一开始就使用了 no-sql)
示例数据
{
"slug": "sample-item-slug",
"Released": "2008",
"Platforms": "Nintendo DS, PSP",
"DevelopedBy": "Sample Developer",
"PublishedBy": "Sample Publisher"
}
我希望能够将 json 对象中的键作为我的 SOLR 文档的字段导入。
如何做到这一点?我看过 Transformers,但似乎没有专门用于此目的的...
有人可以给我一些建议吗?
提前致谢。
我设法解决了我的小问题,解决方案有多种
使用ScriptTransformer
正如@MatsLindh 所说,对于 JSON 列中的字段是动态的情况,最好的方法可能是使用 javascript 函数来转换列数据,将其解析为JSON 字符串并迭代生成的对象以将行添加到列数据。
ScriptTransformer 的示例函数
function splitMetadata(row) {
var metadata;
metadata = JSON.parse(row.get('metadata'));
if (metadata) {
Object.keys(metadata).map(function(key, index) {
row.put(key,metadata[key]);
});
}
return row;
}
正如Solr Docs所说,传递给函数的row
变量是Java Map<String,Object>
类型,因此您可以使用get,put,remove
轻松地向其添加数据。
示例 data-config.xml
使用 ScriptTransformer
根据问题中指定的数据模型,请注意我还使用 RegexTransformer
使用指定的分隔符将字符串拆分为多个值。
<entity name="metadata" query="select metadata from games" transformer="RegexTransformer,script:splitMetada">
<field column="slug" name="attr_platforms" splitBy=" ," />
<field column="Platforms" name="attr_platforms" splitBy=" ," />
<field column="Released" name="release_date_dt" />
<field column="DevelopedBy" name="developer_s" />
<field column="DevelopedBy" name="publisher_s" />
</entity>
使用 MySQL 内联路径运算符 ->>
如果您的列中有固定数量的 json 键,您可以使用 MySQL 的 内联路径运算符 [=56= select 它们], select 在 JSON 列中指定的键,像这样:
样本MySQL查询
基于问题中指定的数据模型
SELECT
metadata->>'$.Released' AS release_date,
metadata->>'$.Platforms' AS platforms,
metadata->>'$.DevelopedBy' AS developer,
metadata->>'$.PublishedBy' AS publisher
FROM games WHERE id='${game.ID}'
作为 ScriptTransformer 解决方案,您可以在 data-config.xml
文件中将 metadata
列(在我的例子中包含 JSON 的列)声明为 <entity>
并且将其作为连接 table 处理,您还可以在数据库上创建 view
以避免在 XML
示例 data-config.xml
使用 MySQL 查询
基于上面指定的查询
<entity name="metadata" query="select metadata->>'$.Released' as release_date,metadata->>'$.Platforms' as platforms,metadata->>'$.DevelopedBy' as developer, metadata->>'$.PublishedBy' as publisher FROM games where id='${game.ID}'">
<field column="release_date" name="release_date_dt" />
<field column="platforms" name="attr_platforms" />
<field column="developer" name="developer_txt" />
<field column="publisher" name="publisher_txt" />
</entity>