Skip to main content

索引配置

本页面描述了如何配置一个索引。

除了 index_id 外,索引配置还允许您定义五个项目:

  • index-uri:它定义了索引文件应存储的位置。
  • 文档映射:它定义了一个文档及其包含的字段如何为给定索引存储和索引。
  • 索引设置:它定义了用于分片的时间戳字段,以及一些更高级的参数,如合并策略。
  • 搜索设置:它定义了默认搜索字段 default_search_fields,即如果用户查询没有明确指定字段时 Quickwit 将搜索的字段列表。
  • 保留策略:它定义了 Quickwit 应保留已索引数据的时间长度。如果不指定,则数据将永久存储。

配置是在创建索引时设置的,并且可以使用 更新端点CLI 进行更改。

配置文件格式

索引配置格式为 YAML。当配置文件中缺少某个键时,将使用默认值。 下面是一个适用于 HDFS 日志数据集的完整示例:

version: 0.7 # File format version.

index_id: "hdfs"

index_uri: "s3://my-bucket/hdfs"

doc_mapping:
mode: lenient
field_mappings:
- name: timestamp
type: datetime
input_formats:
- unix_timestamp
output_format: unix_timestamp_secs
fast_precision: seconds
fast: true
- name: severity_text
type: text
tokenizer: raw
fast:
- tokenizer: lowercase
- name: body
type: text
tokenizer: default
record: position
- name: resource
type: object
field_mappings:
- name: service
type: text
tokenizer: raw
tag_fields: ["resource.service"]
timestamp_field: timestamp
index_field_presence: true

search_settings:
default_search_fields: [severity_text, body]

retention:
period: 90 days
schedule: daily

Index ID

索引 ID 是一个字符串,用于在元存储中唯一标识索引。它只能包含大写或小写的 ASCII 字母、数字、破折号 (-) 和下划线 (_)。最后,它必须以字母开头,并且至少包含 3 个字符但不超过 255 个字符。

Index uri

索引 URI 定义了索引文件(也称为切片)应存储的位置。 此参数期望一个 存储 URI

index-uri 参数是可选的。 默认情况下,index-uri 会通过将 index-idQuickwit 的配置 中定义的 default_index_root_uri 连接起来计算得出。

caution

在分布式模式下运行 Quickwit 时,文件存储将无法工作。相反,在运行多个搜索节点时,应使用 AWS S3、Azure Blob 存储、Google Cloud Storage(在 S3 互操作模式下)或其他 S3 兼容的存储系统,如 Scaleway Object Storage 和 Garage 作为存储。

文档映射

文档映射定义了如何为给定索引存储和索引文档及其包含的字段。文档是一组命名字段的集合,每个字段都有自己的数据类型(文本、字节、日期时间、布尔、i64、u64、f64、IP、JSON)。

变量描述默认值
field_mappings字段映射的集合,每个映射都有其自己的数据类型(文本、二进制、日期时间、布尔、i64、u64、f64、IP、JSON)。[]
mode定义了 Quickwit 如何处理不在 field_mappings 中的文档字段。特别是,“动态”模式使得可以在无模式的方式下使用 Quickwit。(参见 mode)dynamic
dynamic_mappingmode 设置为 dynamic 时才允许此参数。然后它定义了是否应该对动态映射的字段进行索引、存储等。(参见 mode)
tag_fields已经在 field_mappings 中定义的字段集合*,这些字段的值将作为 tags 元数据的一部分存储。了解更多关于标签的信息[]
store_source原始 JSON 文档是否存储在索引中。false
timestamp_field用于将文档分片的日期时间字段*。该字段必须是 datetime 类型。了解更多关于时间分片的信息None
partition_key如果设置,Quickwit 将根据声明为 partition_key 的字段名称将文档路由到不同的切片中。null
max_num_partitions限制通过分区创建的切片数量。(参见 分区)200
index_field_presence对快速字段自动启用 exists 查询。为了对所有其他字段启用它,请将此参数设置为 true。启用它可能会在索引时产生显著的 CPU 开销。false

*: 标签字段和时间戳字段表示为从 JSON 对象根到给定字段的路径。如果字段名称包含一个 . 字符,则需要用 \ 字符转义。

字段类型

每个字段[^1]都有一个类型,指示它包含的数据种类,例如 64 位整数或文本。 Quickwit 支持以下原始类型:texti64u64f64datetimeboolipbytesjson,同时也支持复合类型,如数组和对象。在幕后,Quickwit 使用 tantivy 字段类型,如果您想深入了解细节,请参阅 tantivy 文档

原始类型

文本类型

此字段是一个文本字段,在索引之前会被分析并拆分成令牌。 这种类型的字段适合全文搜索。

文本字段映射示例:

文本字段参数

变量描述默认值
description字段的可选描述。None
stored值是否存储在文档存储中。true
indexed值是否应该被索引以便能够进行搜索。true
tokenizerTokenizer 的名称。(查看分词器)以获取可用分词器的列表。default
record描述索引的信息量,可以选择 basicfreqpositionbasic
fieldnorms是否为字段存储字段规范。字段规范用于计算文档的 BM25 分数。false
fast值是否存储在快速字段中。快速字段将包含术语 ID 和字典。对于 true 的默认行为是不变地存储原始文本。快速字段上的规范化器单独配置。可以通过 normalizer: lowercase 来配置。(查看规范化器)以获取可用规范化器的列表。false
可用分词器的描述
分词器描述
raw不处理也不分词文本。过滤掉大于 255 字节的令牌。
raw_lowercase不分词文本,但将其转换为小写。过滤掉大于 255 字节的令牌。
default根据空白字符和标点符号分割文本,移除过长的令牌,并转换为小写。过滤掉大于 255 字节的令牌。
en_stem类似于 default,但在结果令牌上还应用了词干提取。过滤掉大于 255 字节的令牌。
whitespace仅根据空白字符分割文本。不移除长令牌也不转换为小写。
chinese_compatible除了 default 执行的操作之外,还在每个 CJK 字符之间进行分割。应与 record: position 一起使用以正确地进行搜索。
lowercase对文本应用小写转换。它不分词文本。
可用规范化器的描述
规范化器描述
raw不处理也不分词文本。过滤掉大于 255 字节的令牌。
lowercase对文本应用小写转换。过滤掉大于 255 字节的令牌。

记录选项的描述

记录选项描述
basic仅记录 DocId
freq记录文档 ID 以及术语频率
position记录文档 ID、术语频率以及出现位置。

使用位置索引是执行短语查询所必需的。

数值类型:i64u64f64 类型

Quickwit 支持三种数值类型:i64u64f64

数值值可以存储在快速字段中(相当于 Lucene 的 DocValues),这是一种用于范围查询和聚合的列式存储。

在未指定字段的情况下查询负数(使用 default_search_fields),您应该单引号括起数字(例如 -5),否则它将被解释为匹配除了该数字以外的任何内容。

u64 字段映射示例:

name: rating
description: Score between 0 and 5
type: u64
stored: true
indexed: true
fast: true

数值类型字段 (i64, u64, 和 f64) 参数

变量描述默认值
description字段的可选描述。None
stored字段值是否存储在文档存储中。true
indexed字段值是否被索引。true
fast字段值是否存储在快速字段中。false
coerce是否将作为字符串传递的数字转换为整数或浮点数。true
output_format用于返回搜索结果中数字的 JSON 类型。可能的值为 numberstringnumber

日期时间类型 (datetime)

datetime 类型处理日期和日期时间。由于 JSON 没有日期类型,datetime 字段支持多种输入类型和格式。支持的输入类型包括:

  • 表示 Unix 时间戳的浮点数或整数
  • 包含格式化的日期、日期时间或 Unix 时间戳的字符串

input_formats 字段参数指定了接受的日期格式。以下输入格式得到原生支持:

  • iso8601
  • rfc2822
  • rfc3339
  • strptime
  • unix_timestamp

输入格式

当指定多个输入格式时,相应的解析器会按照声明的顺序尝试。以下格式得到原生支持:

  • iso8601, rfc2822, rfc3339:使用标准的 ISO 和 RFC 格式解析日期。
  • strptime:使用 Unix strptime 格式解析日期,有一些变化:
    • strptime 格式标识符:%C, %d, %D, %e, %F, %g, %G, %h, %H, %I, %j, %k, %l, %m, %M, %n, %R, %S, %t, %T, %u, %U, %V, %w, %W, %y, %Y, %%
    • %f 用于毫秒精度支持。
    • %z 时区偏移可以指定为 (+|-)hhmm(+|-)hh:mm
warning

目前不支持时区名称格式标识符 (%Z)。

  • unix_timestamp:解析浮点数和整数为 Unix 时间戳。浮点值转换为以秒表示的时间戳。整数值转换为 Unix 时间戳,其精度(秒、毫秒、微秒或纳秒)根据输入数字位数推断。内部地,日期时间转换为 UTC(如果指定了时区),并存储为 i64 整数。因此,Quickwit 只支持从 Apr 13, 1972 23:59:55Mar 16, 2242 12:56:31 的时间戳值。
warning

从浮点数到整数值的转换可能会导致精度损失。

datetime 字段存储为快速字段时,fast_precision 参数指示在编码前用于截断值的精度,这有助于压缩(此处的截断意味着清零)。fast_precision 参数可以取以下值:seconds, milliseconds, microseconds, 或 nanoseconds。它只影响标记为“快速”的 datetime 字段在快速字段中存储的内容。最后,对 datetime 快速字段的操作,例如通过聚合,需要在纳秒级别进行。

info

内部地,datetime 在快速字段和文档存储中以 nanoseconds 存储,在术语字典中以 seconds 存储。

此外,Quickwit 支持 output_format 字段参数来指定以何种精度反序列化日期时间。此参数支持与输入格式相同的值,除了 unix_timestamp 被替换为以下格式:

  • unix_timestamp_secs:以秒显示时间戳。
  • unix_timestamp_millis:以毫秒显示时间戳。
  • unix_timestamp_micros:以微秒显示时间戳。
  • unix_timestamp_nanos:以纳秒显示时间戳。

datetime 字段映射示例:

name: timestamp
type: datetime
description: Time at which the event was emitted
input_formats:
- rfc3339
- unix_timestamp
- "%Y %m %d %H:%M:%S.%f %z"
output_format: unix_timestamp_secs
stored: true
indexed: true
fast: true
fast_precision: milliseconds

日期时间字段参数

变量描述默认值
input_formats用于解析输入日期的格式[rfc3339, unix_timestamp]
output_format用于在搜索结果中显示日期的格式rfc3339
stored字段值是否存储在文档存储中true
indexed字段值是否被索引true
fast字段值是否存储在快速字段中false
fast_precision用于存储快速值的精度 (seconds, milliseconds, microseconds, 或 nanoseconds)seconds

布尔类型 (bool)

bool 类型接受布尔值。

布尔字段映射示例:

name: is_active
description: Activation status
type: bool
stored: true
indexed: true
fast: true

布尔字段参数

变量描述默认值
description字段的可选描述。None
stored值是否存储在文档存储中true
indexed值是否被索引true
fast值是否存储在快速字段中false

IP 类型 (ip)

ip 类型接受 IP 地址值,同时支持 IPv4 和 IPv6。内部地,IPv4 地址会被转换为 IPv6。

IP 字段映射示例:

name: host_ip
description: Host IP address
type: ip
fast: true

IP 字段参数

变量描述默认值
description字段的可选描述。None
stored值是否存储在文档存储中true
indexed值是否被索引true
fast值是否存储在快速字段中false

二进制类型 (bytes)

bytes 类型接受一个以 Base64 编码的字符串形式的二进制值。

二进制字段映射示例:

name: binary
type: bytes
stored: true
indexed: true
fast: true
input_format: hex
output_format: hex

二进制字段参数

变量描述默认值
description字段的可选描述。None
stored值是否存储在文档存储中true
indexed值是否被索引true
fast值是否存储在快速字段中。仅支持一对一基数,不支持 array<bytes> 字段false
input_format用于表示输入二进制数据的编码,可以是 hexbase64base64
output_format用于在搜索结果中表示二进制数据的编码,可以是 hexbase64base64

JSON 类型 (json)

json 类型接受一个 JSON 对象。

JSON 字段映射示例:

name: parameters
type: json
stored: true
indexed: true
tokenizer: raw
expand_dots: false
fast:
normalizer: lowercase

JSON 字段参数

变量描述默认值
description字段的可选描述。None
stored值是否存储在文档存储中true
indexed值是否被索引true
fast值是否存储在快速字段中。JSON 中文本的默认行为是不变地存储文本。可以通过 normalizer: lowercase 配置一个标准化器。(查看可用的标准化器) 以获取可用标准化器列表。true
tokenizer仅影响 JSON 对象中的字符串Tokenizer 的名称,可以选择 raw, default, en_stemchinese_compatibleraw
record仅影响 JSON 对象中的字符串。描述索引的信息量,可以选择 basic, freqpositionbasic
expand_dots如果为真,则包含 . 的 JSON 键将被展开。例如,如果 expand_dots 设置为真,则 {"k8s.node.id": "node-2"} 将像 {"k8s": {"node": {"id": "node2"}}} 一样被索引。这样做的好处是在查询时不需要转义 .。换句话说,k8s.node.id:node2 将匹配文档。这不会影响文档的存储方式。true

注意 tokenizerrecord 与文本字段具有相同的定义和相同的效果。

要在 JSON 对象中搜索,则需要扩展字段名以指向目标值的路径。

例如,当索引以下对象时:

{
"product_name": "droopy t-shirt",
"attributes": {
"color": ["red", "green", "white"],
"size:": "L"
}
}

假设 attributes 已经被定义为如下字段映射:

- type: json
name: attributes

attributes.color:red 是一个有效的查询。

如果另外将 attributes 设置为默认搜索字段,那么 color:red 也是一个有效的查询。

复合类型

array(数组)

Quickwit 支持所有原始类型(除了 object 类型)的数组。

要在索引配置中声明一个 i64 类型的数组,只需将类型设置为 array<i64> 即可。

object(对象)

Quickwit 支持嵌套对象,只要它不包含对象数组即可。

name: resource
type: object
field_mappings:
- name: service
type: text

concatenate(拼接)

Quickwit 支持将多个字段的内容映射到单一字段上。这在查询时可能比遍历数十个 default_search_fields 更高效。它还允许在不知道要搜索字段的路径的情况下,在 JSON 字段内进行查询。

name: my_default_field
type: concatenate
concatenated_fields:
- text # things inside text, tokenized with the `default` tokenizer
- resource.author # all fields in resource.author, assuming resource is an `object` field.
include_dynamic_fields: true
tokenizer: default
record: basic

拼接字段不支持快速字段,并且永远不会存储。它们使用自己的分词器,独立于各个字段上配置的分词器。 在查询时,拼接字段不支持范围查询。 仅支持以下类型的拼接字段:text、bool、i64、u64、json。其他类型会在创建索引时被拒绝,或者如果在 JSON 字段中发现,则在索引化过程中被静默丢弃。 向拼接字段添加对象字段不会自动添加其子字段(目前还不支持)。

无法从 JSON 字段添加子字段到拼接字段。例如,如果 attributes 是一个 JSON 字段,则无法仅将 attributes.color 添加到拼接字段中。

对于 JSON 字段和动态字段,仅索引值而不索引路径。例如,给定以下文档:

{
"421312": {
"my-key": "my-value"
}
}

可以搜索 my-value 而不必知道完整的路径,但无法搜索包含键 my-key 的所有文档。

Mode

mode 描述了当 Quickwit 接收到未在字段映射中定义的字段时的行为。

Quickwit 提供了三种不同的模式:

  • dynamic(默认值):未映射的字段会被 Quickwit 收集,并按照 dynamic_mapping 参数中定义的方式处理。
  • lenient:未映射的字段会被 Quickwit 忽略。
  • strict:如果文档包含未映射的字段,Quickwit 将会忽略该文档,并将其计为错误。

动态映射

dynamic 模式使得可以在无模式或部分模式的情况下运行 Quickwit。 dynamic 模式的配置可通过 dynamic_mapping 参数设置。 dynamic_mapping 提供与配置 json 字段相同的配置选项,默认为:

version: 0.7
index_id: my-dynamic-index
doc_mapping:
mode: dynamic
dynamic_mapping:
indexed: true
stored: true
tokenizer: default
record: basic
expand_dots: true
fast: true

dynamic_mapping 设置为已索引(默认),通过动态模式映射的字段可以通过针对从 JSON 对象根部访问它们所需的路径来搜索。

例如,在完全无模式的设置下,最简单的索引配置可能是:

version: 0.7
index_id: my-dynamic-index
doc_mapping:
# If you have a timestamp field, it is important to tell quickwit about it.
timestamp_field: unix_timestamp
# mode: dynamic #< Commented out, as dynamic is the default mode.

有了这样一个简单的配置,我们可以对一个复杂的文档进行索引,如下面所示:

{
"endpoint": "/admin",
"query_params": {
"ctk": "e42bb897d",
"page": "eeb"
},
"src": {
"ip": "8.8.8.8",
"port": 53,
},
//...
}

以下查询是有效的,并匹配上述文档。

// Fields can be searched simply.
endpoint:/admin

// Nested object can be queried by specifying a `.` separated
// path from the root of the json object to the given field.
query_params.ctk:e42bb897d

// numbers are searchable too
src.port:53

// and of course we can combine them with boolean operators.
src.port:53 AND query_params.ctk:e42bb897d

字段名称验证规则

目前 Quickwit 只接受符合以下正则表达式的字段名称: ^[@$_\-a-zA-Z][@$_/\.\-a-zA-Z0-9]{0,254}$

用通俗的语言来说:

  • 需要有至少一个字符。
  • 只能包含大写和小写的 ASCII 字母 [a-zA-Z]、数字 [0-9].、破折号 -、下划线 _、斜杠 /、at 符号 @ 和美元符号 $
  • 不得以点号或数字开头。
  • 必须与 Quickwit 的保留字段映射名称 _source_dynamic_field_presence 不同。
caution

对于包含 . 字符的字段名称,在引用它们时需要对其进行转义。否则 . 字符将被视为 JSON 对象属性的访问。因此,建议避免使用包含 . 字符的字段名称。

对空值或缺失字段的行为

JSON 文档中的 null 值或缺失字段在索引时将被静默忽略。

索引设置

本节描述了给定索引的索引设置。

变量描述默认值
commit_timeout_secs自创建以来提交拆分的最大秒数。60
split_num_docs_target每个拆分的目标文档数。10000000
merge_policy描述触发拆分合并操作所采用的策略(参见下方的 合并策略 部分)。
resources.heap_size每个来源每个索引的索引器堆大小。2000000000
docstore_compression_leveldocstore 中使用的 zstd 压缩级别。较低的值可能会提高摄取速度,但代价是索引大小8
docstore_blocksizedocstore 中块的大小,以字节为单位。较小的值可能会提高文档检索速度,但代价是索引大小1000000

合并策略

Quickwit 使得可以定义用于决定哪些拆分应该合并以及何时合并的策略。

Quickwit 提供了三种不同的合并策略,每种都有自己的参数集。

“稳定日志”合并策略

稳定日志合并策略试图最小化写入放大效应,并尽可能保持较高的时间修剪能力,通过合并大小相似且时间跨度相近的拆分。

Quickwit 默认的合并策略是 stable_log 合并策略,参数如下:

version: 0.7
index_id: "hdfs"
# ...
indexing_settings:
merge_policy:
type: "stable_log"
min_level_num_docs: 100000
merge_factor: 10
max_merge_factor: 12
maturation_period: 48h
变量描述默认值
merge_factor(高级) 在单次合并操作中一起合并的拆分数目。10
max_merge_factor(高级) 在单次合并操作中可以一起合并的最大拆分数目。12
min_level_num_docs(高级) 文档数目低于此值的所有拆分被视为属于同一层级。100000
maturation_period拆分被视为成熟的时间期限,之后将不再考虑进行合并。可能会影响待处理删除任务的完成时间。48h

“限制合并”合并策略

“限制合并”合并策略被认为是高级功能

限制合并策略通过设置拆分应经历的合并操作次数的上限来简单地限制写入放大效应。

version: 0.7
index_id: "hdfs"
# ...
indexing_settings:
merge_policy:
type: "limit_merge"
max_merge_ops: 5
merge_factor: 10
max_merge_factor: 12
maturation_period: 48h
变量描述默认值
max_merge_ops给定拆分应经历的最大合并次数。4
merge_factor(高级) 在单次合并操作中一起合并的拆分数目。10
max_merge_factor(高级) 在单次合并操作中可以一起合并的最大拆分数目。12
maturation_period拆分被视为成熟的时间期限,之后将不再考虑进行合并。可能会影响待处理删除任务的完成时间。48h

不合并

no_merge 合并策略完全禁用合并。

caution

此设置不推荐使用。合并是必要的,因为它可以减少拆分的数量,从而提高搜索性能。

version: 0.7
index_id: "hdfs"
indexing_settings:
merge_policy:
type: "no_merge"

索引器内存使用

索引器默认使用 2 GiB 的堆内存。这并不直接反映总体内存使用情况,但将这个值加倍应该能得到一个合理的近似值。

搜索设置

本节描述了给定索引的搜索设置。

变量描述默认值
default_search_fields用于搜索的默认字段列表。此列表中的字段名称可以在模式中显式声明,也可以引用由动态模式捕获的字段。None

保留策略

本节描述了 Quickwit 如何管理数据保留。在 Quickwit 中,保留策略管理器按拆分删除数据,而不是单独删除文档。拆分根据其 time_range 进行评估,该 time_range 来自索引时间戳字段(在 (doc_mapping.timestamp_field) 设置中指定)。使用此设置,当 now() - split.time_range.end >= retention_policy.period 时,保留策略将删除拆分。

version: 0.7
index_id: hdfs
# ...
retention:
period: 90 days
schedule: daily
变量描述默认值
period以人类可读方式表示的拆分被删除后的持续时间(如 1 day2 hoursa week 等)。必需
schedule以 cron 表达式 (0 0 * * * *) 或人类可读形式 (hourlydailyweeklymonthlyyearly) 表示的保留策略评估和应用的频率。hourly

period 被指定为一系列时间间隔。每个时间间隔是一个整数后跟一个单位后缀,如:2 days 3h 24min。支持的单位有:

  • nsec, ns -- 纳秒
  • usec, us -- 微秒
  • msec, ms -- 毫秒
  • seconds, second, sec, s
  • minutes, minute, min, m
  • hours, hour, hr, h
  • days, day, d
  • weeks, week, w
  • months, month, M -- 一个月定义为 30.44 天
  • years, year, y -- 一年定义为 365.25 天