知识点
相关文章
更多最近更新
更多Solr从Mongodb索引数据(上) 借助mongodb-jdbc和配置JdbcDataSource
2019-03-27 01:01|来源: 网路
Mongodb越来越流行,这边也用Mongodb去存储大量数据.但碰到一个问题,如何通过Solr从Mongodb中获取数据以及索 引?Mongodb提供了DataImportHandler去索引数据,目前支持以下几种数据来 源:JdbcDataSource,ContentStreamDataSource,FieldReaderDataSource,MockDataSource,URLDataSource
用得比较多的还是JdbcDataSource,Solr对它的支持也比较完善,如增量索引.但Mongodb并不支持JDBC(貌似也不可能支持),提供了自己的
Driver:mongo-java-driver,下载地址:https://github.com/mongodb/mongo-java-driver/downloads.
但由于之前项目较紧,自己写个针对Mongodb的DataImportHandler又来不及.于是google下下,找到了mongo-jdbc.下载地址:https://github.com/erh/mongo-jdbc
mongo-jdbc估计就是个翻译,将mongo-java-driver翻译成JDBC,如连接,查询,插入等.自己也没来得及细看.但集成 到Solr中还是发现一些问题,因为Solr中利用JDBC的一些特性mongo-jdbc并不支持,无奈只能修改部分源码来赶鸭子上架.但这也只是权宜 之计,等时间充沛再针对mongodb写一个DataImportHandler吧.
这里先说明下如何使用:
1.建立db-data-config.xml,我这边示例如下:
<dataConfig>
<dataSource driver="com.mongodb.jdbc.MongoDriver" url="mongodb://192.168.1.166/tapp" autoCommit="true"/>
<document>
<entity name="ziyuan" query="select id,name,content, tags from source"
deltaQuery="select id,name,content, tags from item where addTime > '${dataimporter.last_index_time}'">
<field column="_id" name="myid" />
<field column="name" name="name" />
<field column="content" name="content" />
<field column="tags" name="tags" />
</entity>
</document>
</dataConfig>
主要修改dataSource中driver,url.其他基本类似.
2.如此就可以运行了,在浏览器中输入导入http请求,如:http://localhost:8080/solr1.4/core0/dataimport?command=full-import
但发现会报一系列错误.这也是我以上提的,Solr中需要JDBC一些特性,但mongo-jdbc中并不支持.这只能修改源码了.修改地方如下,
主要修改两个类,一个是Solr中的JdbcDataSource,另外一个是mongo-jdbc中的MongoResultSet:
1)org.apache.solr.handler.dataimport.JdbcDataSource
a) 需要替换一个地方,具体看注释
protected Callable<Connection> createConnectionFactory(final Context context, final Properties initProps) {
// 略
if (url != null) {
// 郭芸修改,不支持MongoDB
// 将c = DriverManager.getConnection(url, initProps)替换成如下
//c = DriverManager.getConnection(url, initProps);
if(url.startsWith("mongodb:")){
c=DriverManager.getConnection(url);
}else{
c = DriverManager.getConnection(url, initProps);
}
}
// 略
}
b) 需要替换三个地方,具体请看注释
private class ResultSetIterator {
// 略
public ResultSetIterator(String query) {
// 略
Connection c = getConnection();
// 郭芸修改,MongoDB暂还不支持
// stmt = c.createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY); 替换成如下
/*stmt = c.createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY);*/
stmt = c.createStatement();
// 略
// 郭芸修改,MongoDB-JDBC暂还不支持
// 替换以下注释语句
/*if (stmt.execute(query)) {
resultSet = stmt.getResultSet();
}*/
resultSet=stmt.executeQuery(query);
// 略
// 郭芸修改,MongoDB-JDBC还不支持元数据
// 替换以下注释语句
//colNames = readFieldNames(resultSet.getMetaData());
if(resultSet instanceof MongoResultSet){
MongoResultSet rs=(MongoResultSet)resultSet;
colNames=rs.getColNames();
}else{
colNames = readFieldNames(resultSet.getMetaData());
}
}
}
2)com.mongodb.jdbc.MongoResultSet
a)需要增加一个方法,具体如下:
// 郭芸修改,以便可以获取Field Name,solr中JdbcDataSource需要根据Filed name来匹配以及获取数据
public List<String> getColNames(){
List colNames=new ArrayList();
String colName;
for(int i=1;i<=_fields._ids.size();i++){
colName=this._find(i);
// 由于Mongodb中的id为_id,所以需要替换,否则无法获取id数据
if(colName.equals("id")){
colName="_id";
}
colNames.add(colName);
}
return colNames;
}
最后将修改的类重新编译打包替换之前的包便可运行,我这边运行通过.但增量索引还未验证.
看来还是要自己实现一个DataImportHandler才是王道!
接下来实现...
转自:http://www.cnblogs.com/xuweili/articles/3685771
相关问答
更多-
solr索引导入数据的问题[2023-05-24]
在solr与tomcat整合文章中,我用的索引库是mycore,现在就以这个为例。 首先要准备jar包:solr-dataimporthandler-4.8.1.jar、solr-dataimporthandler-extras-4.8.1.jar和mysql-connector-java-5.0.7-bin.jar这三个包到solr的tomcat的webapps\solr\WEB-INF\lib下 在这个文件夹的conf下配置两个文件,添加一个文件。先配置solrconfig.xml。 在该文件下添加一个 ... -
如何避免在Solr中存储原始内容,只有索引版本?(How to avoid storing the original content in Solr, only the indexed version?)[2022-02-28]
您无需在Solr中存储原始内容。 这是存储和索引之间的区别。 如果将stored设置为false,则只会根据搜索需要保留已处理的标记化内容版本。 只需确保存储您的ID。 这是在schema.xml中的字段定义中设置的。 这意味着Solr无法将任何非存储字段返回给用户,因此您需要根据ID将它们与原始记录匹配(就像您似乎建议的那样)。 这也会破坏部分文档更新,因此您需要确保在更改内容时重新编制整个文档的索引。 You don't have to store original content in Solr. T ... -
你需要用于MongoDB,CouchDB和Cassandra的Solr / Lucene吗?(Do you need Solr/Lucene for MongoDB, CouchDB and Cassandra?)[2023-06-01]
Solr(Lucene)使用算法从查询中返回相关文档。 它将返回一个分数以指示每个文档与查询有多相关。 它与数据库(不管是否有关系)做的不同,它返回的是匹配或不是查询的结果。 Solr (Lucene) uses an algorithm to returns relevant documents from a query. It will returns a score to indicate how relevant each document is related to the query. It i ... -
将Apache Solr与MongoDB一起使用的正确做法是什么?(What are the right practices of using Apache Solr with MongoDB?)[2022-10-15]
如果仅查询Solr是有意义的,那就这样做。 如果查询Solr某些数据是有意义的,那就这样做吧。 这取决于您的使用案例,但如果可以使用Solr中的数据回答任何查询,那么将它用于所有内容就完全没问题了。 这可能会更有效地使用您的缓存。 不,不是我所知道的。 不是真的。 Solr不太适合嵌套的JSON(即使你有父/子文档,它也是你必须在每种情况下手动处理的东西,并且需要特殊的套管)。 在这些情况下,您可以使用Solr进行查询,返回ID,然后从mongo中检索实际文档,其JSON结构完好无损。 在这种情况下,您可以 ... -
NoSQL(MongoDB)vs Lucene(或Solr)作为您的数据库(NoSQL (MongoDB) vs Lucene (or Solr) as your database)[2023-07-17]
这是一个很好的问题,我已经深思熟虑了一些。 我将总结我的经验教训: 几乎所有情况下,您可以轻松地使用Lucene / Solr代替MongoDB,但反之亦然。 格兰特·英格索尔的帖子总结在这里。 MongoDB等似乎是一个不需要搜索和/或刻面的目的。 对于RDBMS世界的程序员来说,这似乎是一个更简单和可以说更容易的过渡。 除非有人习惯了Lucene&Solr有更陡峭的学习曲线。 没有很多使用Lucene / Solr作为数据存储的例子,但是Guardian已经取得了一些进展,并将其概括为一个很好的滑盖 , ... -
DIH没有任何问题。 确保您的数据库连接字符串有效,并且您的数据库已启动并正在运行。 As Eric Wang pointed out I was using wrong port number and after that also I was getting SSL certificate error the final url string that worked for me is: url="jdbc:mysql://127.0.0.1:3306/indcat?useSSL=false&"
-
是的,如果您使用的是Solr 4+,则可以将部分更新推送到Solr索引。 SCHEMA 对于部分更新, 需要存储schema.xml中的所有字段 。 这是您的fields部分在schema.xml中的样子:
MongoDB索引(MongoDB indexes)[2022-06-15]
是的,MongoDB中的_id始终是唯一的。 它是主键,这就是为什么不需要设置UNIQUE原因。 Yes, _id in MongoDB is always unique. It's the primary key, which is why setting UNIQUE isn't necessary.正如在这个SO中所写的那样,Solr的Schemaless模式可以帮助你 Solr支持Schemaless模式 。 以这种方式启动Solr时,您最初并未绑定到架构。 当您向Solr提供第一个文档时,它将猜测相应的字段类型并生成包含这些字段类型的模式。 然后修复这些字段。 您仍然可以通过这种方式添加新字段。 你还需要做的是从你的mongodb到Solr创建某种导入路线。 谷歌搜索后,你可能会偶然发现SO问题 - MongoDB的solr数据导入处理程序 - 这也可能对你有帮助。 可能更简单的是创建一个mong ...从mongo shell中,切换到要从中收集索引的数据库 第1步:切换到现有数据库并在脚本下运行 > use my_existing_db 下面的脚本遍历所有集合并为每个集合构造一个run command 。 var database = ‘my_new_db' // SHOULD ALWAYS MATCH DESTINATION DB NAME db.getCollectionNames().forEach(function(collection){ var command = {} ...