保持elasticsearch和数据库同步

时间:2012-10-03 12:04:36

标签: ruby-on-rails lucene nosql elasticsearch

我试图找到一种方法来保持我的mysql db和elasticsearch db同步。我使用弹性搜索的jprante / elasticsearch-river-jdbc插件设置了一个jdbc河。当我执行以下请求时:

curl -XPUT 'localhost:9200/_river/my_jdbc_river/_meta' -d '{
"type" : "jdbc",
"jdbc" : {
    "driver" : "com.mysql.jdbc.Driver",
    "url" : "jdbc:mysql://localhost:3306/MY-DATABASE",
    "user" : "root",
    "password" : "password",
    "sql" : "select * from users",
    "poll" : "1m"
},
"index" : {
    "index" : "test_index",
    "type" : "user"
}
}'

河流开始索引数据,但对于某些记录,我得到org.elasticsearch.index.mapper.MapperParsingException。那么有关于这个问题的讨论here,但我想知道一种解决这个问题的方法。

是否可以通过为我要编制索引的“类型”的所有“字段”创建explicit mapping来永久解决此问题,还是有更好的方法来解决此问题?

我的另一个问题是,当jdbc-river再次轮询数据库时,它似乎将整个数据集(在sql查询中给出)重新索引到ES中。我不确定,但是这样做是因为elasticsearch想要添加新数据以及更新现有数据中的任何更改吗?如果表的数据是静态的,是否可以仅索引新数据?

2 个答案:

答案 0 :(得分:5)

您是否看过默认映射? http://www.elasticsearch.org/guide/reference/mapping/dynamic-mapping.html

我认为它可以帮到你。

如果数据表中有插入日期字段,则可以使用它来过滤必须编制索引的内容。 见https://github.com/jprante/elasticsearch-river-jdbc#time-based-selecting

HTH

大卫

答案 1 :(得分:0)

Elastic Search完全放弃了河流同步概念。它不是推荐的路径,因为在弹性搜索等文档存储中保持相同的规范化SQL表结构通常没有意义。

比如说,您将Product作为具有某些属性的实体,并将Product实体上的评论作为父子表,因为评论在同一个表上可以是多个。

Products(Id, name, status,... etc)
Product_reviewes(product_id, review_id)
Reviews(id, note, rating,... etc)

在文档商店中,您可能希望创建一个名称为“包含Product{attribute1, attribute1,... Product reviews[review1, review2,...]}

的产品”的索引

以下是在此类设置中同步的方法。

假设:

  1. SQL数据库(真实的记录来源)
  2. 弹性搜索或任何其他NoSql文档存储
  3. 解决方案:

    1. 在JMS / AMQP /数据库队列/文件系统队列/ Amazon SQS等发布事件/事件中发生更新/更新时,完整的产品或主要对象ID(我建议只使用ID)
    2. 如果只将主ID推送到Queue,或者只是将对象自行移动并将相应的更改发送到Elastic search / NoSQL数据库,则队列使用者应该调用Web服务来获取完整对象。