最近在配合研发做ubd的项目,简单的说就是一张大宽表,有200个字段,而且数据量特别巨大(1亿级别的数据量),传统的数据库是不适合的,因此考虑基于lucene的solr,并且推荐使用solr cloud的功能来做高可用和sharding(后面会更新对solr和lucene的代码学习)。

数据从hive计算插入到solr中,根据github上的代码自己做了修改,实现了hive2solr的功能。其实数据的最终插入还是调用了SolrInputDocument类的对应方法。

默认情况下对solr 添加和更新数据使用的是SolrInputDocument的setField和addField方法

(可以把SolrInputField想象成数据库的column,那么SolrInputDocument 就是一个row)

比如:

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:

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 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();
             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 docs = new  ArrayList();
        docs.add(doc);
        server.add(docs);
        server.commit();        
    }
}