本次分析以Solr3.3是最新的版本为准,
Solr3.3接收客户端的查询索引,新建索引请求都是通过过滤器SolrDispatchFilter来提交给SolrCore的Eexecute方法的。而WEB
.xml文件里的Servlet都不取作用的。SolrDispatchFilter主要是根据当前请求路径的PATH,客户端发起的请求PATH主要如下几类:
1 /admin 以adinm开头的则到Solr的管理页面。
2 /select,/update 这类的为对应的Handler /select 即搜索请求,对应的handler为 SearchHandler,/update新建,更新索引对应的handler为XmlUpdateRequestHandler,这里主要讲一下 Solr是怎么对新建索引的XML格式的请求做解析的。
新建索引的命令如下:
<add><doc boost=2.1><field name="id">222</field></doc></add>
XmlUpdateRequestHandler 类是ContentStreamHandlerBase的子类,处理的方法在ContentStreamHandlerBase类的
handleRequestBody方法,该方法的代码有:
//创建一个xml的解析器,实类为XMLLoader XMLLoader继承抽象的ContentStreamLoader
ContentStreamLoader documentLoader = newLoader(req, processor);
documentLoader.load(req, rsp, stream);//开始读取要创建的doc信息。
主要代码如下:
对<add>标签的处理如下:
String currTag = parser.getLocalName();
if (currTag.equals(XmlUpdateRequestHandler.ADD)) {
XmlUpdateRequestHandler.log.trace("SolrCore.update(add)");
addCmd = new AddUpdateCommand();
boolean overwrite = true; // the default
Boolean overwritePending = null;
Boolean overwriteCommitted = null;
//判断add标签是否有其他的属性,主要包过如下几个:
//overwrite,allowDups,commitWithin,overwritePending,overwriteCommitted
for (int i = 0; i < parser.getAttributeCount(); i++) {
String attrName = parser.getAttributeLocalName(i);
String attrVal = parser.getAttributeValue(i);
if (XmlUpdateRequestHandler.OVERWRITE.equals(attrName)) {
overwrite = StrUtils.parseBoolean(attrVal);
} else if (XmlUpdateRequestHandler.ALLOW_DUPS.equals(attrName)) {
overwrite = !StrUtils.parseBoolean(attrVal);
} else if (XmlUpdateRequestHandler.COMMIT_WITHIN.equals(attrName)) {
addCmd.commitWithin = Integer.parseInt(attrVal);
} else if (XmlUpdateRequestHandler.OVERWRITE_PENDING.equals(attrName)) {
overwritePending = StrUtils.parseBoolean(attrVal);
} else if (XmlUpdateRequestHandler.OVERWRITE_COMMITTED.equals(attrName)) {
overwriteCommitted = StrUtils.parseBoolean(attrVal);
} else {
XmlUpdateRequestHandler.log.warn("Unknown attribute id in add:" + attrName);
}
}
// check if these flags are set
if (overwritePending != null && overwriteCommitted != null) {
if (overwritePending != overwriteCommitted) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
"can't have different values for 'overwritePending' and 'overwriteCommitted'");
}
overwrite = overwritePending;
}
//通过下面三行代码,起作用的就是overwrite
addCmd.overwriteCommitted = overwrite;
addCmd.overwritePending = overwrite;
addCmd.allowDups = !overwrite;
对<doc>标签的处理如下:
else if ("doc".equals(currTag)) {
XmlUpdateRequestHandler.log.trace("adding doc...");
addCmd.clear();
addCmd.solrDoc = readDoc(parser);
}
readDoc方法主要是读取<doc>标签和<field>的读取<doc>代码如下:
//Solr 把Luence的Doc封装为SolrInputDocument
SolrInputDocument doc = new SolrInputDocument();
String attrName = "";
for (int i = 0; i < parser.getAttributeCount(); i++) {
attrName = parser.getAttributeLocalName(i);
if ("boost".equals(attrName)) {
doc.setDocumentBoost(Float.parseFloat(parser.getAttributeValue(i)));
} else {
XmlUpdateRequestHandler.log.warn("Unknown attribute doc/@" + attrName);
}
}
从上面的代码可以看出,<doc>标签可以有属性boost,(<doc boost="2">)即可以给该doc设置权重。以改变评分。
读取field的代码就不贴了,相信读者也会想到和上面的是一个模式,会读取 field的name,boost,属性,像<doc>一样,
我们也可以给特定的field设置权重。遇到</field>标签时,代码如下:
doc.addField(name, text.toString(), boost);
boost = 1.0f;
从上面两行代码可以看出,每一个field字段默认的boost为1.0.
Solr解析完<add>命令,创建一个SolrInputDocument 对象,那Solr是怎么把SolrInputDocument 对象转变为luence
的doc对象的呢,在创建时,Solr创建了一个process 这个process是RunUpdateProcessor的实例,上面readDoc方法完成后,返回SolrInputDocument 实例,然后调用RunUpdateProcessor的processAdd方法。把SolrInputDocument 对象转变为luence
doc对象。代码如下:
public void processAdd(AddUpdateCommand cmd) throws IOException {
//转变doc对象
cmd.doc = DocumentBuilder.toDocument(cmd.getSolrInputDocument(), req.getSchema());
//主要是把luence doc写到内存索引
updateHandler.addDoc(cmd);
super.processAdd(cmd);
}
分享到:
相关推荐
solr初学者很受用的!讲解了solr怎么创建索引的及其原理,以及查询
solr创建索引并查询,希望能够帮助有需要的人。。。
索引是设计表的一部分,创建的索引对sql的语句木有任何影响,对sql语句的执行效率有影响
详细阐述Solr-search 源码级别过程
lucene&solr原理分析,lucene搜索引擎和solr搜索服务器原理分析。
solr-6.2.0 强大的分布式搜索引擎,包含各种详细例子及源码解析
solr使用和原理 简单明了的介绍了solr的使用和原理,及其部署方式,适合初学者第一次部署
主要介绍了java多线程处理执行solr创建索引示例,需要的朋友可以参考下
solr6.6.0源码
solr定时索引(增量索引、完整索引)需要用到的jar包和配置 支持7.3版本
在tomcat中配置solr,以及solr 全文搜索建立索引的相关方法总结
Solr数据库插入(全量和增量)索引,全量一般用于第一次创建索引情况,批量一般更新数据部分创建索引。
主要讲解了 solr客户端如何调用带账号密码的solr服务器调用,实现添加索引和查询索引,以及分组查询
楼主实操的步骤整理的,只需要将Zookeeper的ip换成自己集群的就可以一步步地跟着文档实现,感兴趣的同学可以看看。
Weiz.Solr 开发使用一些源码,如何使用检索查询。C#项目映入
Solr 索引 测试报告 性能
介绍了Solr5.5内部使用的分词原理,有助于开发者自定义自己的分词器时掌握分词的基础知识。
solr增量导入更新索引包
大数据Solr架构原理.pdf
Apache Solr 1.3.0发布,Apache Solr是一个性能强大的,基于 Lucene 的全文搜索的 开源企业级搜索服务器,拥有XML/HTTP,JSON APIs,hit highlighting, ...新的DataImportHandler提供简易方式索引数据库内容进入Solr