solr请求回来的数据为字节流,solrj通过JavaBinCodec对其进行解析。
一、JavaBinCodec的主要标识tag
各tag的定义:
public static final byte NULL = 0, BOOL_TRUE = 1, BOOL_FALSE = 2, BYTE = 3, SHORT = 4, DOUBLE = 5, INT = 6, LONG = 7, FLOAT = 8, DATE = 9, MAP = 10, SOLRDOC = 11, //SolrDocument对象,会先读取SortedMap,然后setField到SolrDocument中 SOLRDOCLST = 12, //SolrDocumentList对象,会先读一个长度为3的list即arr,并设置numFound,start,maxScore3个值,然后再读一个list,即doc的list BYTEARR = 13, ITERATOR = 14, /** * this is a special tag signals an end. No value is associated with it */ END = 15, SOLRINPUTDOC = 16, SOLRINPUTDOC_CHILDS = 17, ENUM_FIELD_VALUE = 18, // types that combine tag + length (or other info) in a single byte
//这些tag除了表示tag外还包括了其子元素的个数或其他信息 TAG_AND_LEN = (byte) (1 << 5), STR = (byte) (1 << 5), //表示字符串以及长度,tag范围32~63,&0x1f后得到的就是字符串长度 SINT = (byte) (2 << 5), //表示small int以及长度,tag范围32~95,&0x1f后得到的就是sint的长度 SLONG = (byte) (3 << 5), //表示small long以及长度,tag范围96~111, &0x0f后得到的就是slong的长度 ARR = (byte) (4 << 5), //表示数组以及数组元素个数, tag范围-113~-128, &0x0f后得到的就是数组元素个数 ORDERED_MAP = (byte) (5 << 5), // SimpleOrderedMap (a NamedList subclass, and more common)。Key-->Value,Key是先读EXTERN_STRING,再读Str即真正的key值。范围-65~-96。 NAMED_LST = (byte) (6 << 5), // NamedList,范围-33~-64 EXTERN_STRING = (byte) (7 << 5);//map中的keyvalue的key时会用此tag。 范围-32
二、JavaBinCodec主要方法
1、最主要的方法:readVal()
public Object readVal(DataInputInputStream dis) throws IOException { tagByte = dis.readByte(); // if ((tagByte & 0xe0) == 0) { // if top 3 bits are clear, this is a normal tag // OK, try type + size in single byte switch (tagByte >>> 5) { case STR >>> 5: return readStr(dis); case SINT >>> 5: return readSmallInt(dis); case SLONG >>> 5: return readSmallLong(dis); case ARR >>> 5: return readArray(dis); case ORDERED_MAP >>> 5: return readOrderedMap(dis); case NAMED_LST >>> 5: return readNamedList(dis); case EXTERN_STRING >>> 5: return readExternString(dis); } switch (tagByte) { case NULL: return null; case DATE: return new Date(dis.readLong()); case INT: return dis.readInt(); case BOOL_TRUE: return Boolean.TRUE; case BOOL_FALSE: return Boolean.FALSE; case FLOAT: return dis.readFloat(); case DOUBLE: return dis.readDouble(); case LONG: return dis.readLong(); case BYTE: return dis.readByte(); case SHORT: return dis.readShort(); case MAP: return readMap(dis); case SOLRDOC: return readSolrDocument(dis); case SOLRDOCLST: return readSolrDocumentList(dis); case BYTEARR: return readByteArray(dis); case ITERATOR: return readIterator(dis); case END: return END_OBJ; case SOLRINPUTDOC: return readSolrInputDocument(dis); case ENUM_FIELD_VALUE: return readEnumFieldValue(dis); } throw new RuntimeException("Unknown type " + tagByte); }
2、readSolrDocumentList:读SolrDocumentList
//先得到numFound,start,maxScore三个属性的值,存于List中,设置到solrdocumentlist对象中,再找其包含的doclist public SolrDocumentList readSolrDocumentList(DataInputInputStream dis) throws IOException { SolrDocumentList solrDocs = new SolrDocumentList(); List list = (List) readVal(dis); solrDocs.setNumFound((Long) list.get(0)); solrDocs.setStart((Long) list.get(1)); solrDocs.setMaxScore((Float) list.get(2)); @SuppressWarnings("unchecked") List<SolrDocument> l = (List<SolrDocument>) readVal(dis); solrDocs.addAll(l); return solrDocs; }
3、readSolrDocument:读一个doc
//先获得NameList,再放到doc中
public SolrDocument readSolrDocument(DataInputInputStream dis) throws IOException {
NamedList nl = (NamedList) readVal(dis);//结果其实是OrderedMap,会被转成NamedList
SolrDocument doc = new SolrDocument();
for (int i = 0; i < nl.size(); i++) {
String name = nl.getName(i);
Object val = nl.getVal(i);
doc.setField(name, val);
}
return doc;
}
4、readOrderedMap:读map
//先key后value,key时有EXTERN_STRING的Tag,再是Str_tag public SimpleOrderedMap<Object> readOrderedMap(DataInputInputStream dis) throws IOException { int sz = readSize(dis); SimpleOrderedMap<Object> nl = new SimpleOrderedMap<Object>(); for (int i = 0; i < sz; i++) { String name = (String) readVal(dis); Object val = readVal(dis);//读完key后会读value nl.add(name, val); } return nl; }
5、readArray:读数组list
// public List<Object> readArray(DataInputInputStream dis) throws IOException { int sz = readSize(dis); ArrayList<Object> l = new ArrayList<Object>(sz); for (int i = 0; i < sz; i++) { l.add(readVal(dis)); } return l; }
6、readSize:将tag &0x1f获得大小
public int readSize(DataInputInputStream in) throws IOException { int sz = tagByte & 0x1f; //即如果tagByte<31 (0x1f是31), 则tag还表示个数。 if (sz == 0x1f) sz += readVInt(in); //如果太大,则下一个内容就是大小 return sz; }
7、readSmallInt: &0x0f得到长度
public int readSmallInt(DataInputInputStream dis) throws IOException { int v = tagByte & 0x0F; if ((tagByte & 0x10) != 0) v = (readVInt(dis) << 4) | v; return v; }
8、readExternString
// public String readExternString(DataInputInputStream fis) throws IOException { int idx = readSize(fis); if (idx != 0) {// idx != 0 is the index of the extern string 字符串索引 return stringsList.get(idx - 1); } else {// idx == 0 means it has a string value 即后面是字符串 String s = (String) readVal(fis); if (stringsList == null) stringsList = new ArrayList<String>(); stringsList.add(s); return s; } }
三、举例
返回的byte:
2, -94, -32, 46, 114, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, -93, -32, 38, 115, 116, 97, 116, 117, 115, 6, 0, 0, 0, 0, -32, 37, 81, 84, 105, 109, 101, 6, 0, 0, 0, 0, -32, 38, 112, 97, 114, 97, 109, 115, -93, -32, 33, 113, 36, 105, 100, 58, 49, -32, 34, 119, 116, 39, 106, 97, 118, 97, 98, 105, 110, -32, 39, 118, 101, 114, 115, 105, 111, 110, 33, 50, -32, 40, 114, 101, 115, 112, 111, 110, 115, 101, 12, -125, 97, 96, 0, -127, 11, -93, -32, 34, 105, 100, 33, 49, -32, 36, 110, 97, 109, 101, 33, 49, -32, 41, 95, 118, 101, 114, 115, 105, 111, 110, 95, 7, 20, 43, 47, -61, -44, 64, 0, 0
解析完的结果:
{responseHeader={status=0,QTime=0,params={q=id:1,wt=javabin,version=2}},response={numFound=1,start=0,docs=[SolrDocument{id=1, name=1, _version_=1453307822883209216}]}}
解析过程分析:
版本, ORDERED_MAP Tag(read size: -94&0x1f结果为2,即有两个keyvalue), //第一个keyvalue EXTERN_STRING Tag, 字符串长度(46&0x1f=14), responseHeader, ORDERED_MAP Tag(read size: -93&0x1f结果为3), EXTERN_STRING Tag, Str tag(32是str的tag)字符串长度(38&0x1f=6), status, 下个值是int型(6表示int)(ordermap的key读取完后就会读value), 0(4byte), EXTERN_STRING Tag, 字符串长度(37&0x1f=5), QTime, 下个值是int型(6表示int)(ordermap的key读取完后就会读value), 0(4byte), EXTERN_STRING Tag, 字符串长度(38&0x1f=6), params, ORDERED_MAP Tag(read size: -94&0x1f结果为3), EXTERN_STRING Tag, 字符串长度(33&0x1f=1), q, STR TAG(下个值是string)(36&0x1f=4,即有4个字符), id:1, EXTERN_STRING Tag, 字符串长度(34&0x1f=2), wt, STR TAG(下个值是string)(39&0x1f=7,即有7个字符), javabin, EXTERN_STRING Tag, 字符串长度(39&0x1f=7), version, STR TAG(下个值是string)(33&0x1f=1,即有1个字符), 2, //第二个keyvalue EXTERN_STRING Tag, 字符串长度(40&0x1f=8), response, SOLRDOCLST TAG(12是doclist,即SolrDocumentList对象,有属性numFound,start,maxScore,以及自身是ArrayList<SolrDocument>), ARRAY TAG(-128是arr tag)(-125&0x1f=3, 即有3个属性)(后面的三个属性分别是numFound,start,maxScore,详见readSolrDocumentList), SLONG Tag(96是smalllong tag)(97&0x0f=1)结果是1, SLONG Tag(96&0x0f=0)结果是0, NULL Tag(0表示null), ARRAY Tag(-127&0x1f=1,即有一个元素)(该产生的list会被前面的solrdocumentlist.addAll(list)), SOLRDOC Tag(11是solrdoc tag), ORDERED_MAP Tag(read size: -93&0x1f结果为3), EXTERN_STRING Tag, Str Tag字符串长度(34&0x1f=2), id, Str Tag字符串长度(33&0x1f=1), 1, EXTERN_STRING Tag, Str Tag字符串长度(36&0x1f=4), name, Str Tag字符串长度(33&0x1f=1), 1, EXTERN_STRING Tag, Str Tag字符串长度(41&0x1f=9), _version_, Long Tag(7是Long Tag), 1453307822883209216
注:
(1453307822883209216=1010000101011001011111100001111010100010000000000000000000000)(20=00010100,43=00101011,47=00101111,-61=11000011,-44=11010100,64=01000000,0=00000000,0=00000000)
相关推荐
在中文分词方面,Solr-Solrj配合Solr的中文分析器(如IK Analyzer、Smart Chinese Analyzer或HanLP等)能有效地处理中文文本。这些分析器会将输入的中文字符串拆分成有意义的词语,便于索引和搜索。配置分析器通常在...
Solr-Solrj是Apache Lucene项目下的一个子项目,专门为Apache Solr搜索引擎提供Java客户端库。Solr是一款强大的全文检索服务器,而Solrj则是与之交互的Java API,使得开发人员能够轻松地在Java应用程序中集成Solr的...
SolrJ是Apache Solr项目的Java客户端库,它为与Solr服务器进行交互提供了便利的API。这个压缩包包含了两个版本的SolrJ库:solr-solrj-4.10.3.jar和solr-solrj-5.0.0.jar。这两个版本的差异主要在于对Solr服务器的...
SolrJ的使用是大数据环境中实现高效全文检索和数据分析的关键组件。在Java项目中,正确集成SolrJ所需的jar包对于建立与Solr服务器的连接至关重要。 首先,我们需要理解SolrJ的核心功能。SolrJ提供了一系列API,用于...
SolrJ 6.3.0 是一个针对 Apache Solr 的 Java 客户端库,它使得在 Java 应用程序中与 Solr 服务器进行交互变得更加便捷。Solr 是一个流行的开源搜索引擎,用于处理和索引大量文本数据,提供高效、可扩展的全文搜索...
solrj工具类封装,包括条件批量查询,批量增删改,分段修改。
SolrJ是Apache Solr官方提供的Java客户端库,它使得在Java应用程序中与Solr搜索引擎进行交互变得简单。Solr是一个高性能、可扩展的企业级全文搜索引擎,广泛用于内容索引和搜索。SolrJ提供了丰富的API,允许开发者...
SolrJ是Apache Solr官方提供的Java客户端库,它使得在Java应用程序中与Solr搜索引擎进行交互变得简单。这个压缩包文件包含了SolrJ运行所必需的一些关键库,包括JUnit测试框架、Commons IO和Commons Logging。接下来...
### Solr配置与SolrJ使用详解 #### 一、Solr基本安装与配置 **1. 下载Solr** - **步骤说明**: 从Apache官方镜像站点下载Solr 1.4.1版本。 - **操作详情**: 访问链接`http://apache.etoak.com/lucene/solr/`,...
solr-solrj-4.9.0.jar
SolrJ是Apache Solr官方提供的Java客户端库,它使得在Java应用程序中与Solr进行交互变得简单。这个“solrj使用教程”很可能是为了帮助开发者了解如何使用SolrJ来连接、查询和管理Solr索引。下面将详细介绍SolrJ的...
solr-solrj-4.10.3.jar。
solr-solrj-4.4.0.jar
solr-solrj-6.6.0.jar
solr详细配置教程与solrj的使用
solr部署在tomcat势必要设置用户权限,所以客户端solrj在创建连接的时候也需要用户名加密码
solrJ是Java连接solr进行查询检索和索引更新维护的jar包。
java大数据开发中solrJ所需要的核心包.................
### Solrj 中文教程知识点概览 #### 一、企业搜索引擎方案选型与Solr简介 ##### 1.1 企业搜索引擎方案选型 在选择企业级搜索引擎时,主要考虑的是灵活性、可扩展性和成本效益。对于门户社区等场景来说,搜索引擎的...
主要讲解了 solr客户端如何调用带账号密码的solr服务器调用,实现添加索引和查询索引,以及分组查询