最近在配合研发做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有原子更新的功能,可以实现追加的行为(其实最终还是删除+添加)

参考:

http://stackoverflow.com/questions/16234045/solr-how-to-use-the-new-field-update-modes-atomic-updates-with-solrj

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();        
     }
}