设为首页 收藏本站
查看: 2225|回复: 0

[经验分享] solr入门之多线程操作solr中索引字段的解决

[复制链接]

尚未签到

发表于 2017-12-19 09:53:56 | 显示全部楼层 |阅读模式
import java.io.IOException;  
import java.util.ArrayList;
  
import java.util.Date;
  
import java.util.HashMap;
  
import java.util.List;
  
import java.util.Map;
  
import java.util.Map.Entry;
  
import java.util.Set;
  

  
import javax.annotation.Resource;
  
import javax.management.RuntimeErrorException;
  

  
import org.apache.solr.client.solrj.SolrClient;
  
import org.apache.solr.client.solrj.SolrQuery;
  
import org.apache.solr.client.solrj.SolrServerException;
  
import org.apache.solr.client.solrj.response.QueryResponse;
  
import org.slf4j.Logger;
  
import org.slf4j.LoggerFactory;
  
import org.springframework.beans.factory.annotation.Value;
  
import org.springframework.stereotype.Component;
  

  
import cn.com.mx.gome.search.core.util.MD5Utils;
  
import cn.com.mx.gome.search.core.util.Pinyin4jUtil;
  
import cn.com.mx.gome.search.core.util.SetToStringArrUtils;
  
import cn.com.mx.gome.search.quote.digger.solrbean.ProductBean;
  
import cn.com.mx.gome.suggest.cache.WordCountCache;
  
import cn.com.mx.gome.suggest.domian.BaseSuggestIndex;
  
import cn.com.mx.gome.suggest.solr.SolrServiceWrapper;
  

  
/**
  * 商品类 搜索建议推荐词导入
  * @author songqinghu
  *
  */
  
@Component("fullIndexItemSuggestProcess")

  
public>  

  private Logger logger = LoggerFactory.getLogger(FullIndexItemSuggestProcess.class);
  

  //这里注入一个工厂来生产指定的数据源获取类来获取不同的数据源类--先放着
  

  //solr连接
  @Resource
  private SolrServiceWrapper solrServiceWrapperImpl;
  

  @Value("${SORL_PRODUCT_NAME}") //从 properties 文件里注入 solr连接的名称
  private String solrProductName;
  

  @Value("${SORL_SUGGEST_NAME}")
  private String solrSuggestName;
  

  private  SolrClient itemClient;
  

  private SolrClient suggestClient;
  

  @Override
  public List<BaseSuggestIndex> getBeans(int skip, int limit) {//这里在传一个 參数用来确定数据导入方式
  Map<String, Integer> words ;
  if(false){
  //words = getDataBySQL(skip, limit); //从原始数据库中获取
  }else {
  words= getDataBySolr(skip, limit);//从solr中获取
  }
  

  List<BaseSuggestIndex> assembleBeans = AssembleBeans(words);
  

  return assembleBeans;
  }
  /**
  *
  * @描写叙述:从solr索引库中获取数据
  * @param skip 開始
  * @param limit 步距
  * @return
  * @return List<Product>
  * @exception
  * @createTime:2016年3月25日
  * @author: songqinghu
  */
  private Map<String,Integer> getDataBySolr(int skip, int limit) {
  //查询指定范围内的数据
  SolrQuery query = new SolrQuery();
  query.set("q", "*:*");
  query.setStart(skip);
  query.setRows(limit);
  QueryResponse response;
  Map<String,Integer> words = null;
  try {
  response = itemClient.query(query);
  

  logger.info("skip="+skip+",limit="+limit+",获取到索引数  : "+response.getResults().getNumFound());
  

  List<ProductBean> productBeans = response.getBeans(ProductBean.class);
  //数据处理部分---我要将获取到的数据中的 须要的三个字段的汉字 然后进行记录出现次数和去反复
  words = suggestCollect(productBeans);
  }catch (SolrServerException | IOException  e) {
  logger.error("FullIndexItemSuggestProcess  getDataBySolr :" + e);
  }
  return words;
  }
  //将获取到的数据中的 须要的三个字段的汉字 然后进行记录出现次数和去反复
  private Map<String, Integer> suggestCollect(List<ProductBean> productBeans) {
  

  Map<String, Integer> words = new HashMap<String,Integer>();
  

  for (ProductBean productBean : productBeans) { //这里须要考虑词语切分问题---不太会处理
  

  String name = productBean.getName(); //商品名称
  mapOperation(words, name);
  List<String> cateNames = productBean.getCateName();//类目名称
  for (String cateName : cateNames) {
  mapOperation(words, cateName);
  }
  String spuBrand = productBean.getSpuBrand();//品牌名称
  mapOperation(words, spuBrand);
  

  }
  return words;
  }
  /**
  * 对map中数据进行操作
  */
  private void mapOperation(Map<String, Integer> words,String name){
  if(words.containsKey(name)){ //存在就加一
  Integer count = words.get(name);
  words.put(name, count+1);
  }else{//不存在就存入
  words.put(name, 1);
  }
  }
  

  //对原始查询后的集合数据进行拆分
  public List<BaseSuggestIndex> AssembleBeans(Map<String,Integer> words){
  ArrayList<BaseSuggestIndex> baseSuggestIndexs = new ArrayList<BaseSuggestIndex>();
  Set<Entry<String, Integer>> entrySet = words.entrySet();
  for (Entry<String, Integer> entry : entrySet) {
  BaseSuggestIndex assembleBean = AssembleBean(entry);
  baseSuggestIndexs.add(assembleBean);
  }
  

  return baseSuggestIndexs;
  }
  //组装单个 solr文档对象
  public BaseSuggestIndex AssembleBean(Entry<String, Integer> entry){
  

  BaseSuggestIndex baseIndex = new BaseSuggestIndex();
  

  String word = entry.getKey();
  

  Set<String> shortpy = Pinyin4jUtil.converterToFirstSpellToSet(word);
  

  Set<String> allpy = Pinyin4jUtil.converterToSpellToSet(word);
  

  baseIndex.setWord(word);
  

  baseIndex.setShort_py(SetToStringArrUtils.convertToStringArr(shortpy));
  

  baseIndex.setAll_py(SetToStringArrUtils.convertToStringArr(allpy));
  //这里须要设置一下 使用md5加密算法 来保证 每一个字符串相应的id唯一  涉及到分类问题 可能会出现反复加入分类

  String>  baseIndex.setSuggestId(id);
  

  baseIndex.setType("product");
  

  baseIndex.setCreateTime(new Date().getTime());
  //这里须要特别注意了--涉及到多线程问题了 ---当查询已经存在的词语的时候   查到次数加上当前的次数---
  //存在问题--怎样处理线程顺序保证多个线程是有序的操作呢?---存入映射关系  结束后再次进行次数更新?
  //这里必须要处理下 和实际的数据差距太大了了!!!!!!!!!!!!!
  logger.info("词名: "+word + " 本轮次数 :"+ entry.getValue());
  baseIndex.setCount(getCount4Word(id, entry.getValue()));
  

  return baseIndex;
  }
  /**
  *
  * @描写叙述:获取该词语的数量加上眼下的词语数量---首次从索引库中获取  后缓存到本地中 以后从本地中获取
  * 这里还是不太准确  尽管保证了词语出现次数 通过加锁 可是线程提交时是无法进行控制的 还是存在误差的

  * @param>  * @param count 本轮词语出现的次数
  * @return
  * @return Integer
  * @exception
  * @createTime:2016年3月25日
  * @author: songqinghu
  */

  private Integer getCount4Word(String>  

  return WordCountCache.putCount(id, count);
  }
  

  

  

  /**
  *
  * @描写叙述:通过数据库来获取数据源
  * @param skip
  * @param limit
  * @return
  * @return List<Product>
  * @exception
  * @createTime:2016年3月25日
  * @author: songqinghu
  */
  private Map<String, Integer> getDataBySQL(int skip, int limit) {
  

  return null;
  }
  

  

  @Override
  public long getMaxNum() {//这里也须要依据数据源来配置下
  if(itemClient == null){
  itemClient = solrServiceWrapperImpl.getCollection(solrProductName);
  }
  SolrQuery query = new SolrQuery();
  query.set("q", "*:*");
  long maxNum = 0;
  try {
  maxNum = itemClient.query(query).getResults().getNumFound();
  } catch (SolrServerException | IOException  e) {
  logger.error("FullIndexItemSuggestProcess  getMaxNum :" + e);
  }
  logger.info(new Date()+"  最大值: "+maxNum);
  return maxNum;
  }
  

  @Override
  public boolean isEnd(int skip, int limit, long maxNum) {
  

  //開始坐标要是小于 最大数量就继续---要不要事实更新呢?时时更新吧
  

  return skip < getMaxNum() ? true : false;
  }
  /**
  * 获取词语相应的索引id
  */
  @Override
  public String getId(String word) {
  if(word ==null){
  throw new RuntimeException("id不能为空");
  }
  return "product_"+MD5Utils.MD5(word);
  }
  

  
}
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-425618-1-1.html 上篇帖子: solr启动时报错org.apache.solr.common.SolrException: undefined field text的解决办法 下篇帖子: 7.solr学习速成之facet
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表