Nested查询

更新时间:
复制为 MD 格式

OBJECT类型用于存储嵌套的结构化数据(如用户信息、订单详情),支持将多个字段组合为嵌套结构。当OBJECT字段配置了独立存储(is_nested)后,查询条件必须在同一个嵌套对象内同时满足,避免跨对象的错误匹配。通过Nested查询,您可以精确检索嵌套结构中的数据,适用于需要对复杂对象进行精确匹配和过滤的场景。

使用限制

  • OBJECT类型字段不支持设为主键。

  • OBJECT类型字段不支持多值。

  • OBJECT类型字段不支持作为向量字段。

  • OBJECT类型字段不支持配置数据源和数据处理。

  • OBJECT类型内不支持嵌套向量类型字段。

配置OBJECT字段

在添加表或修改表的字段配置步骤中,您可以添加OBJECT类型字段并配置其schema。

添加OBJECT字段

  1. 在字段配置页面,单击+导入字段或手动添加一行字段。

  2. 字段类型列的下拉框中选择OBJECT

  3. 选择OBJECT类型后,该字段的主键多值选项不可选择,向量字段数据源选项置灰。

配置Schema

  1. 在字段列表的OBJECT字段行中,单击配置schema,页面右侧弹出schema配置抽屉。

  2. 在输入框中填写JSON格式的schema配置。schema配置必须为合法的JSON,且不能为空。

  3. 单击确定,完成schema配置。

Schema用于定义OBJECT字段的内部结构,包括子字段的类型和索引方式。以下是一个包含嵌套结构的schema示例:

{
    "fields": {
        "age": {
            "field_type": "INTEGER",
            "index_type": "NUMBER"
        },
        "name": {
            "field_type": "STRING",
            "index_type": "STRING"
        },
        "tags": {
            "fields": {
                "k1": {
                    "field_type": "STRING",
                    "index_type": "STRING"
                },
                "k2": {
                    "field_type": "STRING",
                    "index_type": "STRING"
                }
            },
            "is_nested": true
        }
    },
    "is_nested": true
}

Schema中各参数说明如下:

参数

是否必选

说明

field_type

字段的基本类型,不能为空。支持STRING、INTEGER、FLOAT等类型。

index_type

索引类型。不支持pack类型。

analyzer

分词器。

multi_value

是否为多值字段。默认值为false。如果非Nested字段,该值会被忽略并统一设为true。

is_nested

是否启用独立存储。默认值为false。设为true时,查询条件必须在同一个嵌套对象内同时满足(Nested语义),避免跨对象的错误匹配。

用户源数据

  • 全量

    JSON格式

    {
    	"className": "c1",
    	"students": [{
    		"age": 6,
    		"name": "s1",
    		"tags": [{
    			"k1": "v1",
    			"k2": "v2"
    		}, {
    			"k1": "v11",
    			"k2": "v22"
    		}]
    	}]
    }

    ha3格式

    CMD=add^_
    className=c1^_
    students=[{"age":6,"name":"s1","tags":[{"k1":"v1","k2":"v2"},{"k1":"v11","k2":"v22"}]}]^_
    ^^  
  • 实时

    [
        {
            "cmd": "add",
            "fields": {
                "className": "c1",
                "students": "[{\"age\":6,\"name\":\"s1\",\"tags\":[{\"k1\":\"v1\",\"k2\":\"v2\"},{\"k1\":\"v11\",\"k2\":\"v22\"}]}]"
            }
        }
    ] 

推送数据

OBJECT字段的值为JSON格式。通过API推送实时数据时,OBJECT字段的值需要以JSON字符串形式传入。

推送数据示例

假设有一个班级表,包含一个普通字段className和一个OBJECT字段students,students字段包含age、nametags子字段。以下是推送一条数据的示例:

[
    {
        "cmd": "add",
        "fields": {
            "className": "c1",
            "students": "[{\"age\":6,\"name\":\"s1\",\"tags\":[{\"k1\":\"v1\",\"k2\":\"v2\"},{\"k1\":\"v11\",\"k2\":\"v22\"}]}]"
        }
    }
]
说明

OBJECT字段的值在实时推送时需要转义为JSON字符串。例如上述示例中,students字段的值是一个JSON数组的字符串形式。

上述示例为简化展示,仅包含普通字段和OBJECT字段。实际推送时,需包含表中定义的所有必填字段(如向量字段)。

Nested查询

配置OBJECT字段并推送数据后,您可以在查询中引用OBJECT内部的子字段。子字段的引用路径使用下划线(_)连接,从OBJECT字段名开始,依次拼接各级子字段名。

说明

在向量检索版中,query参数用于向量检索请求中的条件过滤,需配合向量查询的其他参数(如vector、topK等)一起使用。本文仅展示query参数中OBJECT子字段的引用方式。

查询语法

OBJECT内部字段的引用格式为:OBJECT字段名_子字段名。对于多层嵌套,依次用下划线拼接:OBJECT字段名_子字段1_子字段2

例如,对于OBJECT字段students,其子字段age的查询路径为students_age,嵌套子字段tags.k1的查询路径为students_tags_k1

Nested查询行为

schemais_nested设为true时,查询条件必须在同一个嵌套对象内同时满足。这意味着:

  • 如果OBJECT字段包含多个对象(数组),每个查询条件的匹配必须来自同一个数组元素。

  • 不同数组元素之间的字段值不会被交叉匹配。

查询示例

假设已推送以下数据,OBJECT字段studentstags子字段配置了is_nested: true

{
    "className": "c1",
    "students": [
        {
            "age": 6,
            "name": "s1",
            "tags": [
                {"k1": "v1", "k2": "v2"},
                {"k1": "v11", "k2": "v22"}
            ]
        }
    ]
}

示例一:跨对象查询(无结果)

查询条件:classNamec1,students -> tags -> k1v1,students -> tags -> k2v22。

query=className:c1 AND students_tags_k1:v1 AND students_tags_k2:v22

查询结果:无结果。因为k1=v1k2=v22分别属于tags数组中的不同对象(第一个对象的k1v1,第二个对象的k2v22),由于启用了Nested独立存储,条件不在同一个嵌套对象内,因此不匹配。

示例二:同对象查询(有结果)

查询条件:classNamec1,students -> tags -> k1v1,students -> tags -> k2v2。

query=className:c1 AND students_tags_k1:v1 AND students_tags_k2:v2

查询结果:返回匹配数据。因为k1=v1k2=v2属于tags数组中的同一个对象(第一个对象),条件在同一个嵌套对象内同时满足。

{
    "className": "c1",
    "students": "[{\"age\":6,\"name\":\"s1\",\"tags\":[{\"k1\":\"v1\",\"k2\":\"v2\"},{\"k1\":\"v11\",\"k2\":\"v22\"}]}]"
}

非独立存储模式对比

schemais_nested设为false(默认值)时,OBJECT字段的子字段采用扁平化存储。此时查询不要求条件在同一个嵌套对象内匹配,不同对象中的字段值可能会被交叉匹配。

您可以通过查看OBJECT字段的schema配置,确认其中是否包含"is_nested": true来判断当前的存储模式。如果schema中未包含该参数或值为false,则表示采用扁平化存储。

对比项

独立存储(is_nested: true)

扁平化存储(is_nested: false)

匹配方式

条件必须在同一个嵌套对象内同时满足

条件可跨对象匹配

适用场景

需要精确匹配嵌套对象内部关系的场景,如查询"同一标签的k1k2"

只需判断字段值是否存在,不关心值属于哪个嵌套对象的场景

查询示例结果

k1:v1 AND k2:v22 无结果(v1v22不在同一对象)

k1:v1 AND k2:v22 有结果(v1v22分别存在于某个对象中)