1.SolrUpdateRequest请求处理过程详解: SolrUpdateRequest请求处理过程详解: 1.web.xml里启动SolrUpdateServlet |--> init() |-->legacyUpdateHandler = new XmlUpdateRequestHandler() |用于处理提交的xml文档 |-->init()初始化 |-->hasMulticore |通过多core的xml(默认solr.xml)文件进行判断 |--> String instanceDir = SolrResourceLoader.locateInstanceDir(); |--> File fconf = new File(instanceDir, "solr.xml"); 2.SolrUpdateServlet接受update更新请求 |-->doPost() |-->BufferedReader() = Request.getReader() |获取post请求的xml文档 |-->legacyUpdateHandler.dolegacyUpdate(requestReader, writer); |真正处理update请求 3.legacyUpdateHandler.dolegacyUpdate处理详情 |-->processorFactory = core.getUpdateProcessingChain(null); |构建update处理工厂 |-->获取updateProcess的处理链,processorFactory在SolrCore初始化时处理 |-->loadUpdateProcessorChains() |首先从solrconfig.xml中获取 UpdateRequestProcessorChain的plugin |--> 如果获取为空,则设置默认的RunUpdateProcessorFactory,LogUpdateProcessorFactory |-->XMLLoader loader = (XMLLoader) newLoader(req, processor); |生成新的XMLLoader对象,用于处理update请求 |-->loader.processUpdate(processor, parser); |--> AddUpdateCommand addCmd = null; |生成更新的command对象 |--> XMLStreamReader parser |通过XMLStreamReader对象,进行提交的doc文档的解析 4.XMLStreamReader parser解析过程 |-->case:END_DOCUMENT:parser.close(); |结尾标志关闭 |-->case:START_ELEMENT |开始处理逻辑 |-->XmlUpdateRequestHandler.ADD |判断overwritePending,overwriteCommitted,allowDups三个变量 |-->"doc".equals(currTag) |此时为文档,进行文档操作 |-->addCmd.solrDoc = readDoc(parser); |解析Doc文档,为文档添加域 |-->doc.addField(name, text.toString(), boost); |-->processor.processAdd(addCmd); |利用processorFactory处理添加文档,默认处理如下 |-->RunUpdateProcessorFactory |-->LogUpdateProcessorFactory |主要是日志操作 6.>RunUpdateProcessorFactory 处理过程 |-->cmd.doc = DocumentBuilder.toDocument(cmd.getSolrInputDocument(), req.getSchema()); |将SolrDocument转换为lucene的Docment |-->SchemaField sfield = schema.getFieldOrNull(name); |首先由域名获取SchemField,检查是否为field或者dynamicField |-->SchemaField sf = schema.getUniqueKeyField(); |UniqueKeyField设定Doc的id值 |-->Field f = binaryField.createField(sfield,v,boost); |处理binaryField字段 |--> DateField df = (DateField) sfield.getType(); |处理DataField字段 |-->ist<CopyField> copyFields = schema.getCopyFieldsList(name); |处理copyDields字段 |-->SchemaField field : schema.getRequiredFields() |最后处理requiredField必须字段 |-->updateHandler.addDoc(cmd); |获取updateHandler进行文档添加处理 |-->super.processAdd(cmd); |链式处理形式,逐个ProcessorFactory进行处理,返回父类继续处理下一个 7.updateHandler.addDoc(cmd) |-->addCommands.incrementAndGet |增加文档计数加1,添加文档可以是多线程,此时用原子类型 addCommandsCumulative.incrementAndGet |-->if(idField == null) |如果id唯一域为空,则此时设置为可以重复 |-->cmd.allowDups = true; cmd.overwriteCommitted = false; cmd.overwritePending = false; |-->iwAccess.lock(); |读写锁的写锁锁定 |-->openWriter(); |打开IndexWriter,进行写操作 |--> if (cmd.overwriteCommitted || cmd.overwritePending) |可重复提交,添加 |-->Term idTerm = this.idTerm.createTerm(cmd.indexedId); |构造updateTerm |-->writer.updateDocument(updateTerm, cmd.getLuceneDocument(schema)); |lucene底层实现更新文档操作 |-->if(del) |如果需要删除,则删除旧文档 |--> writer.deleteDocuments(bq); |删除文档 |--> else |->writer.addDocument(cmd.getLuceneDocument(schema)); |此时直接添加,允许重复 2.示例文档 <?xml version="1.0" encoding="GBK"?> <docs> <add overwrite="true"> <doc boost="1.0f"> <field name="gmtModified">20101102</field> <field name="pubDate">20101102</field> <field name="sex">2</field> <field name="keywords">hello</field> <field name="requireNum"> 5 </field> <field name="scope">hello </field> <field name="status">1</field> <field name="workWay">2</field> <field name="companyName">hello</field> <field name="deleted">0</field> <field name="city">hello</field> <field name="mode">2</field> <field name="id">4740</field> <field name="title">hello</field> <field name="description">hello</field> <field name="province">湖南</field> <field name="shopLevel">100001</field> <field name="catalogs">杭州</field> <field name="salary">1</field> <field name="eduLevel">0</field> <field name="companyId">3224</field> </doc> </add>