`
wangzjie
  • 浏览: 74968 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Solrj JavaBinCodec分析

    博客分类:
  • solr
阅读更多

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 5.0.0 demo

    在中文分词方面,Solr-Solrj配合Solr的中文分析器(如IK Analyzer、Smart Chinese Analyzer或HanLP等)能有效地处理中文文本。这些分析器会将输入的中文字符串拆分成有意义的词语,便于索引和搜索。配置分析器通常在...

    solr-solrj-6.1.0

    Solr-Solrj是Apache Lucene项目下的一个子项目,专门为Apache Solr搜索引擎提供Java客户端库。Solr是一款强大的全文检索服务器,而Solrj则是与之交互的Java API,使得开发人员能够轻松地在Java应用程序中集成Solr的...

    solr-solrj-4.10.3.jar和solr-solrj-5.0.0.jar

    SolrJ是Apache Solr项目的Java客户端库,它为与Solr服务器进行交互提供了便利的API。这个压缩包包含了两个版本的SolrJ库:solr-solrj-4.10.3.jar和solr-solrj-5.0.0.jar。这两个版本的差异主要在于对Solr服务器的...

    SolrJ需要的jar包

    SolrJ的使用是大数据环境中实现高效全文检索和数据分析的关键组件。在Java项目中,正确集成SolrJ所需的jar包对于建立与Solr服务器的连接至关重要。 首先,我们需要理解SolrJ的核心功能。SolrJ提供了一系列API,用于...

    SolrJ6.3.0

    SolrJ 6.3.0 是一个针对 Apache Solr 的 Java 客户端库,它使得在 Java 应用程序中与 Solr 服务器进行交互变得更加便捷。Solr 是一个流行的开源搜索引擎,用于处理和索引大量文本数据,提供高效、可扩展的全文搜索...

    solrj工具类封装

    solrj工具类封装,包括条件批量查询,批量增删改,分段修改。

    solrj的使用

    SolrJ是Apache Solr官方提供的Java客户端库,它使得在Java应用程序中与Solr搜索引擎进行交互变得简单。Solr是一个高性能、可扩展的企业级全文搜索引擎,广泛用于内容索引和搜索。SolrJ提供了丰富的API,允许开发者...

    solrJ 需要的jar文件 (全)

    SolrJ是Apache Solr官方提供的Java客户端库,它使得在Java应用程序中与Solr搜索引擎进行交互变得简单。这个压缩包文件包含了SolrJ运行所必需的一些关键库,包括JUnit测试框架、Commons IO和Commons Logging。接下来...

    solr配置和solrJ的使用

    ### Solr配置与SolrJ使用详解 #### 一、Solr基本安装与配置 **1. 下载Solr** - **步骤说明**: 从Apache官方镜像站点下载Solr 1.4.1版本。 - **操作详情**: 访问链接`http://apache.etoak.com/lucene/solr/`,...

    solr-solrj-4.9.0.jar

    solr-solrj-4.9.0.jar

    solrj使用教程

    SolrJ是Apache Solr官方提供的Java客户端库,它使得在Java应用程序中与Solr进行交互变得简单。这个“solrj使用教程”很可能是为了帮助开发者了解如何使用SolrJ来连接、查询和管理Solr索引。下面将详细介绍SolrJ的...

    solr-solrj-4.10.3.jar

    solr-solrj-4.10.3.jar。

    solr-solrj-4.4.0.jar

    solr-solrj-4.4.0.jar

    solr-solrj-6.6.0.jar

    solr-solrj-6.6.0.jar

    solr详细配置教程与solrj的使用

    solr详细配置教程与solrj的使用

    solrj创建连接工厂

    solr部署在tomcat势必要设置用户权限,所以客户端solrj在创建连接的时候也需要用户名加密码

    solr-solrj-5.5.0.jar

    solrJ是Java连接solr进行查询检索和索引更新维护的jar包。

    solrJ所需要的核心包

    java大数据开发中solrJ所需要的核心包.................

    Solrj 中文教程

    ### Solrj 中文教程知识点概览 #### 一、企业搜索引擎方案选型与Solr简介 ##### 1.1 企业搜索引擎方案选型 在选择企业级搜索引擎时,主要考虑的是灵活性、可扩展性和成本效益。对于门户社区等场景来说,搜索引擎的...

    java solr solrj 带账号密码增量查询添加索引

    主要讲解了 solr客户端如何调用带账号密码的solr服务器调用,实现添加索引和查询索引,以及分组查询

Global site tag (gtag.js) - Google Analytics