zoukankan      html  css  js  c++  java
  • solr&lucene3.6.0源码解析(三)

    solr索引操作(包括新增 更新 删除 提交 合并等)相关UML图如下

    从上面的类图我们可以发现,其中体现了工厂方法模式及责任链模式的运用

    UpdateRequestProcessor相当于责任链模式中的处理器角色,我们通过如下的对象图也许更能反映多个UpdateRequestProcessor类型的处理器的活动行为

    UpdateRequestProcessorChain为请求处理器链,供客户端调用(内部依赖处理器工厂数组生成不同的处理器)

    public final class UpdateRequestProcessorChain implements PluginInfoInitialized
    {
      private UpdateRequestProcessorFactory[] chain;
      private final SolrCore solrCore;
    
      public UpdateRequestProcessorChain(SolrCore solrCore) {
        this.solrCore = solrCore;
      }
    
      public void init(PluginInfo info) {
        List<UpdateRequestProcessorFactory> list = solrCore.initPlugins(info.getChildren("processor"),UpdateRequestProcessorFactory.class,null);
        if(list.isEmpty()){
          throw new RuntimeException( "updateRequestProcessorChain require at least one processor");
        }
        chain = list.toArray(new UpdateRequestProcessorFactory[list.size()]); 
      }
    
      public UpdateRequestProcessorChain( UpdateRequestProcessorFactory[] chain , SolrCore solrCore) {
        this.chain = chain;
        this.solrCore =  solrCore;
      }
    
      public UpdateRequestProcessor createProcessor(SolrQueryRequest req, SolrQueryResponse rsp) 
      {
        UpdateRequestProcessor processor = null;
        UpdateRequestProcessor last = null;
        for (int i = chain.length-1; i>=0; i--) {
          processor = chain[i].getInstance(req, rsp, last);
          last = processor == null ? last : processor;
        }
        return last;
      }
    
      public UpdateRequestProcessorFactory[] getFactories() {
        return chain;
      }
    }

    UpdateRequestProcessorFactory为请求处理器抽象工厂类,用于实例化请求处理器(UpdateRequestProcessor),而具体的实例化过程延迟到子类实现

    /**
     * A factory to generate an UpdateRequestProcessor for each request.  
     * 
     * If the factory needs access to {@link SolrCore} in initialization, it could 
     * implement {@link SolrCoreAware}
     * 
     * @since solr 1.3
     */
    public abstract class UpdateRequestProcessorFactory implements NamedListInitializedPlugin
    {    
      public void init( NamedList args )
      {
        // could process the Node
      }
      
      abstract public UpdateRequestProcessor getInstance( 
          SolrQueryRequest req, SolrQueryResponse rsp, UpdateRequestProcessor next );
    }

    请求处理器抽象类UpdateRequestProcessor,持有对自身类型的引用(责任链模式的体现)

    /**
     * This is a good place for subclassed update handlers to process the document before it is 
     * indexed.  You may wish to add/remove fields or check if the requested user is allowed to 
     * update the given document...
     * 
     * Perhaps you continue adding an error message (without indexing the document)...
     * perhaps you throw an error and halt indexing (remove anything already indexed??)
     * 
     * By default, this just passes the request to the next processor in the chain.
     * 
     * @since solr 1.3
     */
    public abstract class UpdateRequestProcessor {
      protected final Logger log = LoggerFactory.getLogger(getClass());
    
      protected final UpdateRequestProcessor next;
    
      public UpdateRequestProcessor( UpdateRequestProcessor next) {
        this.next = next;
      }
    
      public void processAdd(AddUpdateCommand cmd) throws IOException {
        if (next != null) next.processAdd(cmd);
      }
    
      public void processDelete(DeleteUpdateCommand cmd) throws IOException {
        if (next != null) next.processDelete(cmd);
      }
    
      public void processMergeIndexes(MergeIndexesCommand cmd) throws IOException {
        if (next != null) next.processMergeIndexes(cmd);
      }
    
      public void processCommit(CommitUpdateCommand cmd) throws IOException
      {
        if (next != null) next.processCommit(cmd);
      }
    
      /**
       * @since Solr 1.4
       */
      public void processRollback(RollbackUpdateCommand cmd) throws IOException
      {
        if (next != null) next.processRollback(cmd);
      }
    
      public void finish() throws IOException {
        if (next != null) next.finish();    
      }
    }

    具体工厂类RunUpdateProcessorFactory及具体请求处理器RunUpdateProcessor

    /**
     * Pass the command to the UpdateHandler without any modifications
     * 
     * @since solr 1.3
     */
    public class RunUpdateProcessorFactory extends UpdateRequestProcessorFactory 
    {
      @Override
      public UpdateRequestProcessor getInstance(SolrQueryRequest req, SolrQueryResponse rsp, UpdateRequestProcessor next) 
      {
        return new RunUpdateProcessor(req, next);
      }
    }
    
    class RunUpdateProcessor extends UpdateRequestProcessor 
    {
      private final SolrQueryRequest req;
      private final UpdateHandler updateHandler;
    
      public RunUpdateProcessor(SolrQueryRequest req, UpdateRequestProcessor next) {
        super( next );
        this.req = req;
        this.updateHandler = req.getCore().getUpdateHandler();
      }
    
      @Override
      public void processAdd(AddUpdateCommand cmd) throws IOException {
        cmd.doc = DocumentBuilder.toDocument(cmd.getSolrInputDocument(), req.getSchema());
        updateHandler.addDoc(cmd);
        super.processAdd(cmd);
      }
    
      @Override
      public void processDelete(DeleteUpdateCommand cmd) throws IOException {
        if( cmd.id != null ) {
          updateHandler.delete(cmd);
        }
        else {
          updateHandler.deleteByQuery(cmd);
        }
        super.processDelete(cmd);
      }
    
      @Override
      public void processMergeIndexes(MergeIndexesCommand cmd) throws IOException {
        updateHandler.mergeIndexes(cmd);
        super.processMergeIndexes(cmd);
      }
    
      @Override
      public void processCommit(CommitUpdateCommand cmd) throws IOException
      {
        updateHandler.commit(cmd);
        super.processCommit(cmd);
      }
    
      /**
       * @since Solr 1.4
       */
      @Override
      public void processRollback(RollbackUpdateCommand cmd) throws IOException
      {
        updateHandler.rollback(cmd);
        super.processRollback(cmd);
      }
    }

    命令参数

    /** An index update command encapsulated in an object (Command pattern)
     *
     * @version $Id: UpdateCommand.java 1065312 2011-01-30 16:08:25Z rmuir $
     */
      public class UpdateCommand {
        protected String commandName;
    
        public UpdateCommand(String commandName) {
          this.commandName = commandName;
        }
    
        @Override
        public String toString() {
          return commandName;
        }
      }

    AddUpdateCommand命令

    /**
     * @version $Id: AddUpdateCommand.java 1145201 2011-07-11 15:18:47Z yonik $
     */
    public class AddUpdateCommand extends UpdateCommand {
       // optional id in "internal" indexed form... if it is needed and not supplied,
       // it will be obtained from the doc.
       public String indexedId;
    
       // The Lucene document to be indexed
       public Document doc;
    
       // Higher level SolrInputDocument, normally used to construct the Lucene Document
       // to index.
       public SolrInputDocument solrDoc;
    
       public boolean allowDups;
       public boolean overwritePending;
       public boolean overwriteCommitted;
       
       public Term updateTerm;
       public int commitWithin = -1;
       
    
       /** Reset state to reuse this object with a different document in the same request */
       public void clear() {
         doc = null;
         solrDoc = null;
         indexedId = null;
       }
    
       public SolrInputDocument getSolrInputDocument() {
         return solrDoc;
       }
    
       public Document getLuceneDocument(IndexSchema schema) {
         if (doc == null && solrDoc != null) {
           // TODO??  build the doc from the SolrDocument?
         }
         return doc;    
       }
    
       public String getIndexedId(IndexSchema schema) {
         if (indexedId == null) {
           SchemaField sf = schema.getUniqueKeyField();
           if (sf != null) {
             if (doc != null) {
               schema.getUniqueKeyField();
               Fieldable storedId = doc.getFieldable(sf.getName());
               indexedId = sf.getType().storedToIndexed(storedId);
             }
             if (solrDoc != null) {
               SolrInputField field = solrDoc.getField(sf.getName());
               if (field != null) {
                 indexedId = sf.getType().toInternal( field.getFirstValue().toString() );
               }
             }
           }
         }
         return indexedId;
       }
    
       public String getPrintableId(IndexSchema schema) {
         SchemaField sf = schema.getUniqueKeyField();
         if (indexedId != null && sf != null) {
           return sf.getType().indexedToReadable(indexedId);
         }
    
         if (doc != null) {
           return schema.printableUniqueKey(doc);
         }
    
         if (solrDoc != null && sf != null) {
           SolrInputField field = solrDoc.getField(sf.getName());
           if (field != null) {
             return field.getFirstValue().toString();
           }
         }
         return "(null)";
       }
    
       public AddUpdateCommand() {
         super("add");
       }
    
       @Override
      public String toString() {
         StringBuilder sb = new StringBuilder(commandName);
         sb.append(':');
         if (indexedId !=null) sb.append("id=").append(indexedId);
         sb.append(",allowDups=").append(allowDups);
         sb.append(",overwritePending=").append(overwritePending);
         sb.append(",overwriteCommitted=").append(overwriteCommitted);
         return sb.toString();
       }
     }

    DeleteUpdateCommand命令

    /**
     * @version $Id: DeleteUpdateCommand.java 1235304 2012-01-24 15:39:17Z janhoy $
     */
    public class DeleteUpdateCommand extends UpdateCommand {
      public String id;    // external (printable) id, for delete-by-id
      public String query; // query string for delete-by-query
      public boolean fromPending;
      public boolean fromCommitted;
      public int commitWithin = -1;
    
      public DeleteUpdateCommand() {
        super("delete");
      }
    
      @Override
      public String toString() {
        StringBuilder sb = new StringBuilder(commandName);
        sb.append(':');
        if (id!=null) sb.append("id=").append(id);
        else sb.append("query=`").append(query).append('`');
        sb.append(",fromPending=").append(fromPending);
        sb.append(",fromCommitted=").append(fromCommitted);
        sb.append(",commitWithin=").append(commitWithin);
        return sb.toString();
      }
    }

    --------------------------------------------------------------------------- 

    本系列solr&lucene3.6.0源码解析系本人原创 

    转载请注明出处 博客园 刺猬的温驯 

    本人邮箱: chenying998179#163.com (#改为@)

    本文链接http://www.cnblogs.com/chenying99/p/3501172.html  

  • 相关阅读:
    系统架构图
    数据分析学习一
    ASP.NET Web APIs 基于令牌TOKEN验证的实现(保存到DB的Token)
    Web API 令牌(秘钥是双方约定的,并不在网络连接上传输)
    【MVC】ASP.NET MVC Forms验证机制
    细说ASP.NET Forms身份认证
    MVC身份验证及权限管理
    [置顶] Web用户的身份验证及WebApi权限验证流程的设计和实现 (不是Token驗證!!!不是Token驗證!!!都是基於用户身份的票据信息驗證!!!)
    WebApi安全性 使用TOKEN+签名验证 (秘钥是GUID的,私有的,不是雙方的,并不在网络连接上传输)
    WebService 简单安全验证
  • 原文地址:https://www.cnblogs.com/chenying99/p/3501172.html
Copyright © 2011-2022 走看看