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

[经验分享] 如何在SOLR中嵌入自己的分词系统

[复制链接]

尚未签到

发表于 2015-7-17 12:01:50 | 显示全部楼层 |阅读模式
SOLR虽然为我们提供了分词的接入方法,但很显然并不奏效,搜遍了大江南北,也没有什么可参考的,大部分都是使用的IK或庖丁之类的分词~~,难 不成就这样永远活在别人的阴影中??答案是"NO!",如果是这样那就意味着屏蔽词管理,词典实时更新,实时持久化等多个个性化的产品需求得以在这些分词 系统上半路杀入,老鸟应该都明白这种做法的成本是太高了。   SOLR推荐但失败的分词接入方法是在schema.xml字段配置文件中写入以下配置:
  
  编写自己的TokenFactory ,该类继成自 SOLR的BaseTokenizerFactory ,找到以下配置节点,并将 tokenizer的 class类 :替换掉。
  



view plaincopy to clipboardprint?

  •    
  •   

  •             
  •       
  •       
  •          
  •          
  •      
  •       
  •          

  •    
  •             
  •          
  •          
  •      
                      把IK的源代码翻了个底朝天,也没看出自己的分词器和它的接入方法有什么区别,不是QUERY分词失败,就是写入的索引没有分词效果,一气之下就钻到SOLR的源代码里,经过一番苦战,终于苦尽甘来~,彻底搞定!
  废话少说,来解决方案:
  说明:因为修改了SOLR的部分代码,所以分词器在SCHEMA.xml的配置是彻底失效了,但是其他字段设定都沿用schema.xml.
  
  在这之前先说下SOLR加载schema.xml的步骤:
  调用栈:
  org.apache.solr.core.SolrCore 520行
  schema = new IndexSchema(config, IndexSchema.DEFAULT_SCHEMA_FILE, null);
  org.apache.solr.schema.IndexSchema 103行
  readSchema(lis);
  SOLR主要是通过 private void readSchema(InputStream is)  这个函数对分词解析器进行初始化,及对schema.xml中的各种类型进行实例化,同时写入到 :protected final HashMap analyzers ,供外部系统调用。
  这次我们开到的函数就是 org.apache.solr.schema.IndexSchema  的 readSchema()函数。
  因为我们要将自己的分词解析器半路插进去,因此在这个函数的这个位置插入以下语句:
  



view plaincopy to clipboardprint?

  • try{  
  •                 AbstractPluginLoader fieldLoader = new AbstractPluginLoader(  
  •                         "[schema.xml] fieldType", true, true) {  

  •                     @Override
  •                     protected FieldType create(ResourceLoader loader, String name,  
  •                             String className, Node node) throws Exception {
  •                         FieldType ft = (FieldType) loader.newInstance(className);
  •                         ft.setTypeName(name);

  •                         String expression = "./analyzer[@type='query']";  
  •                         Node anode = (Node) xpath.evaluate(expression, node,
  •                                 XPathConstants.NODE);
  •                         Analyzer queryAnalyzer = readAnalyzer(anode);

  •                         // An analyzer without a type specified, or with  
  •                         // type="index"  
  •                         expression = "./analyzer[@type='index']";  
  •                         anode = (Node) xpath.evaluate(expression, node,
  •                                 XPathConstants.NODE);
  •                         Analyzer analyzer = readAnalyzer(anode);

  •                         if (queryAnalyzer == null)  
  •                             queryAnalyzer = analyzer;
  •                         if (analyzer == null)  
  •                             analyzer = queryAnalyzer;
  •                         if (analyzer != null) {  
  •                             if(ft!=null && className.equals("solr.TextField")){  
  •                                 ft.setAnalyzer(AnalyzerManager.getAnalyzer());
  •                                 ft.setQueryAnalyzer(AnalyzerManager.getAnalyzer());
  •                             }else{  
  •                                 ft.setAnalyzer(analyzer);
  •                                 ft.setQueryAnalyzer(analyzer);
  •                             }

  •                         }
  •                         return ft;  
  •                     }
try{ AbstractPluginLoader fieldLoader = new AbstractPluginLoader( "[schema.xml] fieldType", true, true) {  @Override protected FieldType create(ResourceLoader loader, String name, String className, Node node) throws Exception { FieldType ft = (FieldType) loader.newInstance(className); ft.setTypeName(name);  String expression = "./analyzer[@type='query']"; Node anode = (Node) xpath.evaluate(expression, node, XPathConstants.NODE); Analyzer queryAnalyzer = readAnalyzer(anode);  // An analyzer without a type specified, or with // type="index" expression = "./analyzer[@type='index']"; anode = (Node) xpath.evaluate(expression, node, XPathConstants.NODE); Analyzer analyzer = readAnalyzer(anode);  if (queryAnalyzer == null) queryAnalyzer = analyzer; if (analyzer == null) analyzer = queryAnalyzer; if (analyzer != null) { if(ft!=null && className.equals("solr.TextField")){ ft.setAnalyzer(AnalyzerManager.getAnalyzer()); ft.setQueryAnalyzer(AnalyzerManager.getAnalyzer()); }else{ ft.setAnalyzer(analyzer); ft.setQueryAnalyzer(analyzer); }  } return ft; }        在 protected FieldType create(ResourceLoader loader, String name,
       String className, Node node) throws Exception {  
  这个函数体中,判断 className 的类名,因为我们需要对solr.TextField类型做重写,即改写text类型的分词器,所以需要加入以下判断:
  



view plaincopy to clipboardprint?

  • if (analyzer != null) {  
  •                             if(ft!=null && className.equals("solr.TextField")){  
  •                                 ft.setAnalyzer(AnalyzerManager.getAnalyzer());
  •                                 ft.setQueryAnalyzer(AnalyzerManager.getAnalyzer());
  •                             }else{  
  •                                 ft.setAnalyzer(analyzer);
  •                                 ft.setQueryAnalyzer(analyzer);
  •                             }

  •                         }
if (analyzer != null) { if(ft!=null && className.equals("solr.TextField")){ ft.setAnalyzer(AnalyzerManager.getAnalyzer()); ft.setQueryAnalyzer(AnalyzerManager.getAnalyzer()); }else{ ft.setAnalyzer(analyzer); ft.setQueryAnalyzer(analyzer); }  }      OK,重启SOLR,试试看,是不是奏效了??

运维网声明 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-87647-1-1.html 上篇帖子: Solr索引数据库数据 下篇帖子: (七) solr数据导入:通过JDBC从数据库导入数据
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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