多元索引提供了Long、Double、Boolean、Keyword、Text和GeoPoint等基本类型。除了基本类型外,还提供了两种特殊的类型。

一种是数组,数组属于附加类型,可以附加在Long、Double、Boolean、Keyword、Text和GeoPoint等类型之上。例如Long类型 + 数组后,那就是数组长整型,该字段中可以包括多个长整型数字,查询的时候其中任何一个匹配都可以返回该行数据。

另一种是嵌套类型,有点像数组,但是功能更丰富。

数组类型

基本类型的数组形式,例如:

  • Long Array

    长整型的数组形式,格式:“[1000, 4, 5555]”。

  • Boolean Array

    布尔值的数组形式,格式:“[true, false]”。

  • Double Array

    浮点数的数组形式,格式:“[3.1415926, 0.99]”。

  • Keyword Array

    字符串的数组形式,格式:“[杭州, 西安]”。

  • Text Array

    文本的数组形式,格式:“[杭州, 西安]”,对于Text类型是否数组区别不大,一般不这么用。

  • GeoPoint Array

    地理位置点的数组形式,格式:“[[34.2, 43.0], [21.4,45.2]]”。

数组类型仅是多元索引中的概念,表中还未支持数组,索引对于数组类型的字段,在表中都必须是String类型,对应的多元索引中的类型必须是相应的类型,例如Long、Double等。例如有一个字段price是Double Array类型,那么在表中price必须是string类型,在多元索引中必须是double类型,且附加isArray=true属性。

嵌套类型

嵌套类型(Nested)代表嵌套文档类型,嵌套文档是指对于一行数据(文档)可以包含多个子文档,多个子文档保存在一个嵌套类型的列中。对于一个嵌套类型的列,需要指定其子文档的结构,即子文档中包含哪些字段,以及每个字段的属性。以Java代码为例:

// 构造子文档的FieldSchema
List<FieldSchema> subFieldSchemas = new ArrayList<FieldSchema>();
subFieldSchemas.add(new FieldSchema("tagName", FieldType.KEYWORD)
    .setIndex(true).setEnableSortAndAgg(true));
subFieldSchemas.add(new FieldSchema("score", FieldType.DOUBLE)
    .setIndex(true).setEnableSortAndAgg(true));

// 将子文档的FieldSchema设置到NESTED列的subfieldSchemas中。
FieldSchema nestedFieldSchema = new FieldSchema("tags", FieldType.NESTED)
    .setSubFieldSchemas(subFieldSchemas);

上面的代码定义了一个嵌套类型列的格式,这列列名为tags,子文档中包含两个字段,其中一个字段名为tagName,类型为字符串类型(KEYWORD),另一个Field名为score,类型为浮点数(DOUBLE)。

嵌套类型列在写入时是作为字符串类型写到主表的,字符串的格式是JSON对象的数组。按照上面例子里定义的Nested格式,可以再举一个数据格式的例子,例如:

[{"tagName":"tag1", "score":0.8}, {"tagName":"tag2", "score":0.2}]

即这一列中包含了两个子文档。需要注意,即使只有一个子文档,也应该按照JSON数组的格式构造字符串。

嵌套类型的局限性:
  1. 使用了嵌套类型的索引不支持IndexSort功能,而IndexSort功能在很多场景下可以带来很大性能提升。
  2. 嵌套类型的查询性能相比其他类型的查询性能更低一些。

嵌套类型除了上述局限性外,和非嵌套类型支持的功能一样,支持所有查询Query,支持排序以及未来的统计聚合。

如果想了解更多Array和Nested的对比,可以阅读这篇文章:《Array和Nested对比》。