使用 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>