最近在配合研发做ubd的项目,简单的说就是一张大宽表,有200个字段,而且数据量特别巨大(1亿级别的数据量),传统的数据库是不适合的,因此考虑基于lucene的solr,并且推荐使用solr cloud的功能来做高可用和sharding(后面会更新对solr和lucene的代码学习)。
数据从hive计算插入到solr中,根据github上的代码自己做了修改,实现了hive2solr的功能。其实数据的最终插入还是调用了SolrInputDocument类的对应方法。
默认情况下对solr 添加和更新数据使用的是SolrInputDocument的setField和addField方法
(可以把SolrInputField想象成数据库的column,那么SolrInputDocument 就是一个row)
比如:
1
2
3
|
SolrInputDocument doc =
new
SolrInputDocument();
doc.addField(
"id"
,
1
);
doc.setField(
"name"
,
"xxxxx"
);
|
但是setField和addField是覆盖的行为,这里数据是从6张表分别计算插入的,就会导致最终数据只有一个表的。
solr有原子更新的功能,可以实现追加的行为(其实最终还是删除+添加)
参考:
demo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
import
java.util.ArrayList;
import
java.util.Collection;
import
java.util.Map;
import
java.util.LinkedHashMap;
import
org.apache.solr.client.solrj.SolrServer;
import
org.apache.solr.client.solrj.impl.HttpSolrServer;
import
org.apache.solr.common.SolrInputDocument;
public
class
User {
public
static
void
main(String[] args)
throws
Exception {
String[] fields = {
"name1_s"
,
"name2_s"
,
"name4_s"
};
Map<String, Object> setOper =
null
;
String url =
"http://xxxxx:8888/solr/userinfo"
;
SolrServer server =
new
HttpSolrServer(url);
SolrInputDocument doc =
new
SolrInputDocument();
//构造一个SolrInputDocument对象
System.out.println(doc.keySet().size());
//0
doc.addField(
"id"
,
"1"
);
for
(
int
i =
0
; i< fields.length; i++){
setOper =
new
LinkedHashMap<String,Object>();
setOper.put(
"set"
,
"a2"
);
//当发现设置的字段值是Map类型时就认为是原子更新
System.out.println(fields[i]);
if
(!doc.keySet().contains(fields[i])){
//防止重复的列
doc.addField(fields[i], setOper);
}
}
System.out.println(doc.keySet().size());
//4
Collection<SolrInputDocument> docs =
new
ArrayList<SolrInputDocument>();
docs.add(doc);
server.add(docs);
server.commit();
}
}
|
本文转自菜菜光 51CTO博客,原文链接:http://blog.51cto.com/caiguangguang/1599137,如需转载请自行联系原作者