指引 (Reference)
数组数据类型(Array_data_type)

数组

在 Milvus 中,数组(Array)是一个有序的元素集合,每个元素可以是特定的数据类型:INT、VARCHAR、BOOL、FLOAT 或 DOUBLE。当你需要在单个字段中存储多个值时,数组特别有用。

单个数组内的所有元素必须是相同的数据类型。

为了演示使用数组字段,我们准备了一个包含 Medium.com 从 2020 年 1 月到 2020 年 8 月发布的文章的数据集 a dataset from Kaggle (opens in a new tab)

在这个主题中,我们加载数据集中的前 100 个实体,并将 linkpublication 字段的值组织成一个名为 var_array 的数组字段,将 reading_timeclapsresponses 的值组织成一个名为 int_array 的数组字段。

数据结构类似于以下示例:

{
 
		'title': 'The Reported Mortality Rate of Coronavirus Is Not Important',
		'title_vector': [0.041732933, 0.013779674, -0.027564144, ..., 0.030096486],
		'var_array': ['https://medium.com/swlh/the-reported-mortality-rate-of-coronavirus-is-not-important-369989c8d912', 'The Startup'],
		'int_array': [13, 1100, 18]
 
}

供参考,以下代码可用于处理示例数据集:

import pandas as pd
 
# 加载下载的数据集的前100个实体
df = pd.read_csv('New_Medium_Data.csv', nrows=100)
for i in range(100):
	df['title_vector'][i] = eval(df['title_vector'][i])
 
# 将指定字段转换为数组
df['var_array'] = df[['link', 'publication']].values.tolist()
df['int_array'] = df[['reading_time', 'claps', 'responses']].values.tolist()
 
# 删除原始列
df = df.drop(columns=['link', 'publication', 'reading_time', 'claps', 'responses'])
 
# 将DataFrame转换为字典列表
data = df.to_dict('records')

定义数组字段

    I provide the content of the markdown document that needs to be translated. Only the headings, paragraphs, and list content in markdown syntax need to be translated. Words in camel case and underscore do not need to be translated. Please retain the punctuations of md syntax. After you finish translating, replace the original content and return the result to me.
    
    When defining an array field, specify the following arguments for elements in the array field:

    - `element_type`: (Required) Data type of elements in an array. Valid values: `DataType.Int8`, `DataType.Int16`, `DataType.Int32`, `DataType.Int64`, `DataType.VARCHAR`, `DataType.BOOL`, `DataType.FLOAT`, and `DataType.DOUBLE`.
    - `max_capacity`: (Required) Maximum number of elements that an array field can contain. Value range: [1, 4,096].
    - `max_length`: Maximum length of strings for each VARCHAR element in an array field. This argument is required when `element_type` is set to `DataType.VARCHAR`. Value range: [1, 65,535].

    ```python
    # Define array fields

    from pymilvus import connections, Collection, FieldSchema, CollectionSchema, DataType

    connections.connect(host='localhost', port='19530')

    # 1. define fields
    fields = [
        FieldSchema(name='id', dtype=DataType.INT64, is_primary=True, auto_id=False, max_length=100),
        FieldSchema(name='title', dtype=DataType.VARCHAR, max_length=512),
        FieldSchema(name='title_vector', dtype=DataType.FLOAT_VECTOR, dim=768),
        # define ARRAY field with VARCHAR elements
        FieldSchema(name='var_array', dtype=DataType.ARRAY, element_type=DataType.VARCHAR, max_capacity=900, max_length=1000),
        # define ARRAY field with INT64 elements
        FieldSchema(name='int_array', dtype=DataType.ARRAY, element_type=DataType.INT64, max_capacity=900)
    ]

    # 2. enable dynamic schema in schema definition
    schema = CollectionSchema(
            fields, 
            "The schema for a medium news collection", 
            enable_dynamic_field=True # Optional, defaults to 'False'.
    )

    # 3. reference the schema in a collection
    collection = Collection("medium_articles_with_array", schema)

    # 4. index the vector field
    index_params = {
        "index_type": "AUTOINDEX",
        "metric_type": "L2",
        "params": {}
    }

    collection.create_index(
      field_name="title_vector", 
      index_params=index_params
    )

    # 5. load the collection
    collection.load()
    ```

    ## Insert field values

    Once the collection is created, you can insert the processed data into it.

    <div class="alert note">

    If `auto_id` is set to `True` for a collection, insert data without the primary key field. Otherwise, an error can occur during data insert.

    </div>

    ```python
    # Insert field values

    # 1. insert data
    collection.insert(data)

    # 2. call the flush API to make inserted data immediately available for search
    collection.flush()

    print("Entity counts: ", collection.num_entities)

    # Output
    # Entity counts:  100
    ```

    ## Search or query with array fields

Limits

使用相同的方式搜索或查询数组字段,就像使用标量字段一样。

使用 int_array 进行搜索,过滤 reading_time 在 10 与 20 之间(不包括 10 和 20)的实体。

# 1. 使用 `int_array` 进行搜索
result = collection.search(
    data=data[0]['title_vector'],
    anns_field='title_vector',
    param={"metric_type": "L2", "params": {"nprobe": 10}},
    limit=3,
    expr='10 < int_array[0] < 20',
    output_fields=['title','int_array']
)
 
for hits in result:
    print("匹配的 ID:", hits.ids)
    print("与查询向量的距离:", hits.distances)
    print("匹配的文章:")
    for hit in hits:
        print(
            "标题:", 
            hit.entity.get("title"), 
            ",阅读时间:", 
            hit.entity.get("int_array")[0]
        )

使用 var_array 进行查询,过滤 publication'The Startup' 的实体。

# 2. 使用 `var_array` 进行查询
result = collection.query(
    expr='var_array[1] == "The Startup"',
    output_fields=['title','var_array']
)
 
for hits in result:
    print("匹配的 ID:", hits.id)
    print("匹配的文章:")
    for hit in hits:
        print(
            "标题:",
            hit.entity.get("title"),
            ",出版物:",
            hit.entity.get("var_array")[1]
        )

检查 int_array 是否包含元素 10

# 3. 使用 array_contains 检查数组是否包含特定元素
 
collection.query(
    expr='array_contains(int_array, 10)',
    output_fields=['title','int_array']
)

限制

在使用数组字段时,可以使用双引号("")或单引号('')将字符串值括起来。需要注意的是,Milvus 将字符串值存储在数组字段中时,不会执行语义转义或转换。例如,'a "b'" a'b "'a'b'" a"b" 会原样保存,而 'a'b' 和 **"a" b " ** 会被视为无效值。

假设已经定义了两个数组字段 int_arrayvar_array。以下表格描述了在使用数组字段进行搜索时,在 expr 中支持的布尔表达式。

运算符示例备注
<'int_array [0] < 3'当  int_array [0]  的值小于 3 时,该表达式为真。
>'int_array [0] > 5'当  int_array [0]  的值大于 5 时,该表达式为真。
=='int_array [0] == 0'当  int_array [0]  的值等于 0 时,该表达式为真。
!='var_array [0] != "a"'当  var_array [0]  的值不等于  "a"  时,该表达式为真。
<='int_array [0] <= 3'当  int_array [0] 的值小于或等于 3 时,该表达式为真。
>='int_array [0] >= 10'当  int_array [0] 的值大于或等于 10 时,该表达式为真。
in'var_array [0] in ["str1", "str2"]'当  var_array [0] 的值为 "str1" "str2" 时,该表达式为真。
not in'int_array [0] not in [1, 2, 3]'当  int_array [0] 的值不为 1、2 或 3 时,该表达式为真。
+, -, *, /, %, **'int_array [0] + 100 > 200'当  int_array [0] + 100 的值大于 200 时,该表达式为真。
like (LIKE)'var_array [0] like "prefix%"'当  var_array [0] 的值以 "prefix" 开头时,该表达式为真。
and (&&)'var_array [0] like "prefix%" && int_array [0] <= 100'当  var_array [0] 的值以 "prefix" 开头,并且  int_array [0] 的值小于或等于 100 时,该表达式为真。
or (||)'var_array [0] like "prefix%" || int_array [0] <= 100'当  var_array [0] 的值以 "prefix" 开头,或者  int_array [0] 的值小于或等于 100 时,该表达式为真。
array_contains (ARRAY_CONTAINS)'array_contains(int_array, 100)' int_array 包含元素 100 时,该表达式为真。
array_contains_all (ARRAY_CONTAINS_ALL)'array_contains_all(int_array, [1, 2, 3])' int_array 包含所有元素 1 2 3 时,该表达式为真。
array_contains_any (ARRAY_CONTAINS_ANY)'array_contains_any(var_array, ["a", "b", "c"])' var_array 包含任意元素 "a" "b" "c" 时,该表达式为真。
array_length'array_length(int_array) == 10' int_array 包含恰好 10 个元素时,该表达式为真。

下一步操作