SchemaAnalyzer
Schema的分析器详细介绍,用法、默认设置
什么是分析器(Analyzer)?
分析器(Analyzer)是将原始文本转换为结构化、可搜索格式的关键组件。
每个分析器通常由两个核心部件组成:标记器和过滤器。它们共同将输入文本转换为标记,完善这些标记,并为高效索引和检索做好准备
核心组成:
Tokenizer(分词器 / 标记化器):将文本切分为独立的词或子词单元。
Filter(过滤器):对标记进行处理,如转小写、去停用词、词干提取等。
分析器 = Tokenizer + 0个或多个 Filters
内置分词器
Milvus的内置分析器预先配置了特定的分词器和过滤器,您可以立即使用,而无需自己定义
standard:适用于文本处理,应用标准标记化和小写过滤
english:针对英语文本进行了优化,支持英语停止词
chinese:专门用于处理中文文本,包括针对中文语言结构的标记化。
重要
这个是milvus提供的内置写法,只支持上面三种
analyzer_params = {
"type": "standard"
}内置过滤器
Milvus 预先配置,只需最少的设置。您只需指定过滤器的名称,就能立即使用这些过滤器
lowercase:将文本转换为小写,确保不区分大小写进行匹配
asciifolding:将非 ASCII 字符转换为 ASCII 对应字符,简化多语言文本处理
alphanumonly:只保留字母数字字符,删除其他字符。有关详情
cnalphanumonly:删除包含除汉字、英文字母或数字以外的任何字符的标记
cncharonly:删除包含任何非汉字的标记
重要
可直接使用的内置过滤器
analyzer_params = {
"tokenizer": "standard", # 指定分词器
"filter": ["lowercase"], # 内置将文本转换为小写的过滤器
}自定义过滤器
自定义过滤器允许进行专门配置。您可以通过选择有效的过滤器类型 (filter.type) 并为每种过滤器类型添加特定设置来定义自定义过滤器
stop:通过设置停止词列表(如"stop_words": ["of", "to"] )删除指定的常用词
length:根据长度标准(如设置最大标记长度)排除标记
stemmer:将单词还原为词根形式,以便更灵活地进行匹配
重要
上面三个自定义过滤器
analyzer_params = {
"tokenizer": "standard", # 指定分词器
"filter": [
{
"type": "stop", # 指定 'stop' 作为过滤器类型
"stop_words": ["of", "to"], # 为此过滤器类型自定义停用词
}
]
}支持的分词器(Tokenizers)
Milvus 支持多种分词器,用于将原始文本切分为词项(tokens)。以下是常用分词器及其功能说明:
Standard: 这是最常用的分词器之一,它根据标准规则将文本分割成词项。例如,它会识别单词边界,并将文本如
"Hello, world!"分割为"Hello"和"world"两个词项。Whitespace: 这个分词器非常简单,它仅仅根据空白字符(空格、制表符等)来分割文本。这意味着
"Hello, world!"将被分割为"Hello,"和"world!"两个词项,保留了标点符号。Jieba: 这是一个专门为中文设计的分词器,基于 Jieba 分词库。它可以准确地识别中文词语边界,这对于处理中文文本非常重要,因为中文没有明确的词间分隔符。
Lindera: 类似于 Jieba,但它是针对日文设计的分词器,能够有效地处理日文文本的分词问题。
ICU: ICU (International Components for Unicode) 是一个强大的国际化工具包,它的分词器可以支持多种语言的文本处理,包括但不限于英语、法语、德语等。
重要
上面只支持自定义格式写法
analyzer_params = {
"tokenizer": "whitespace",
"filter": ["lowercase"]
}支持的过滤器(Filters)
过滤器用于对标记(tokens)进行后处理,提升搜索质量和一致性。Milvus 支持以下过滤器类型:
🔤 基础处理类
- Lowercase: 将所有词项转换为小写形式,确保不区分大小写的匹配。
- ASCII Folding: 将非 ASCII 字符转换为其最接近的 ASCII 等价字符,有助于简化多语言文本的处理。
- Remove Punct: 移除标点符号,确保它们不会干扰文本处理过程。
- Alphanumonly: 只保留字母数字字符,删除其他字符,这在某些场景下可以帮助去除噪声。
🇨🇳 中文专用类
- Cnalphanumonly: 删除包含除汉字、英文字母或数字以外的任何字符的标记,适用于需要严格控制中文文本内容的场景。
- Cncharonly: 删除包含任何非汉字的标记,只保留纯汉字内容。
🧠 语义优化类
- Stop: 去除停用词,即那些在文本中频繁出现但对搜索意义不大的词,如“的”、“是”、“在”等。
- Stemmer: 词干提取,将词还原到其基本形式,以便更灵活地进行匹配,如将“running”还原为“run”。
- Decompounder: 对复合词进行分解,适用于德语等语言,将长复合词拆分为更小的组成部分。
- Length: 根据长度标准排除标记,比如设置最小和最大长度,可以用来过滤掉过短或过长的词项。
⚙️ 高级定制类
- Regex: 使用正则表达式定义复杂的过滤规则,提供高度定制化的文本处理能力。
- Multi-Language: 处理多语言文本时,可能需要特定的过滤逻辑来适应不同语言的特点。
重要
上面只支持自定义格式写法
analyzer_params = {
"tokenizer": "whitespace",
"filter": ["lowercase"]
}案例
重要
怎么样创建完整milvus案例
import pandas as pd
from pymilvus import DataType
from basecofig.embedding import Embedding
from basecofig.milvus import Milvus
milvus= Milvus()
milvus1 = milvus.get_milvus()
einit = Embedding()
embedding = einit.get_embedding()
# 分析器是用来进行全局查询的
def creat_data():
"""
结合分析词,自定义创建,动态添加字段
"""
if not milvus1.has_collection("reviews_collection_shema_text"):
# 创建新的shema对象 自动生成主键 动态添加字段
schema = milvus1.create_schema(auto_id=True,enable_dynamic_field=True)
# 创建分析器
analyzer_params_builtin = {
"type": "chinese"
}
# 错误 我这个数据是已经分析器分好的,所以不需要分
# schema.add_field(field_name="vector",datatype=DataType.FLOAT_VECTOR,dim=1024,analyzer_params_builtin=analyzer_params_builtin)
schema.add_field(
field_name="vector",
datatype=DataType.FLOAT_VECTOR,
dim=1024
)
schema.add_field(
field_name="text",
datatype=DataType.VARCHAR,max_length=1024,
analyzer_params=analyzer_params_builtin
)
schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True)
# 准备索引参数
index_params = milvus1.prepare_index_params()
# 为向量字段添加索引(关键)
index_params.add_index(
field_name="vector",
index_type="AUTOINDEX", # 让 Milvus 自动选择最合适的索引类型
metric_type="COSINE" # 语义相似度
)
# 创建集合
milvus1.create_collection(
collection_name="reviews_collection_shema_text", # 创建集合名称
schema=schema,
index_params=index_params
)
print("自定义集合创建成功")
def add_data():
"""
添加数据
"""
# 获取表格数据
df = pd.read_excel("../data/好坏评论.xlsx")
df = df[['user_shop_id', 'comment_content', 'create_time']].
dropna(subset=['comment_content'])
# 提取 comment_content 字段的数据
comment_contents = df['comment_content'].tolist() # 去除空值并转为列表
vectors = embedding.embed_documents(comment_contents) # 传整个列表,不是循环单个
# 将数据插入 Milvus
data = []
for i, row in df.iterrows():
entity = {
"user_shop_id": row['user_shop_id'],
"create_time": row['create_time'],
"text": row['comment_content'],
"vector": vectors[i] # 对应的向量
}
data.append(entity)
# 插入方法
res = milvus1.insert(
collection_name="reviews_collection_shema_text",
data=data
)
print(res)
def qurey_data():
data_in_db = milvus1.query(
collection_name="reviews_collection_shema_text",
# filter=f"user_shop_id LIKE '325%'", # 必须是字符串
filter=f"text LIKE '中%'",
output_fields=["*"],
limit=120 # 显式限制最多返回 1000 条(根据需要调整)
)
print(data_in_db)
print(f" 读取 {len(data_in_db)} 条好评数据")
if __name__ == '__main__':
# creat_data()
# add_data()
qurey_data()小结:如何选择分析器?
| 场景 | 推荐方案 |
|---|---|
| 通用英文文本 | "english" 内置分析器 |
| 通用中文文本 | "chinese" 或 jieba + cnalphanumonly |
| 多语言混合 | standard + lowercase + asciifolding |
| 精确匹配字段(如 ID) | keyword tokenizer |
| 模糊搜索 / 拼写纠错 | ngram + lowercase |
| 日志分析 | whitespace + alphanumonly |
milvus默认分析器
- 自定义的配置没有默认分析器
- 手动定义的配置配置 analyzer_params 时,这个字段才会具备分词、关键词检索的能力
analyzer_params_builtin = {
"type": "chinese"
}
schema.add_field(
field_name='title_en',
datatype=DataType.VARCHAR,
max_length=1000,
enable_analyzer=True,
analyzer_params=analyzer_params_built_in,
enable_match=True,
)默认自动创建的数据库也不支持
分析器的作用 ?
- Analyzer 对原始文本进行分词处理,用于关键词搜索。
- Vector 支持的语义搜索通过将查询文字转换为向量来做匹配。
尽管这种方法可以工作,但可能不如基于分词的关键词搜索那么精准。
向量匹配和分词匹配的对比
| 字段 | 类型 | 是否启用 analyzer | 用途 |
|---|---|---|---|
| text | VARCHAR / TEXT | ✅ 是 | 存原始评论,支持关键词搜索(如“服务差”) |
| vector | FLOAT_VECTOR | ❌ 否 | 存嵌入向量,支持语义相似搜索(如找意思相近的评论) |
MySQL vs. Milvus 搜索对比
| 维度 | MySQL (LIKE) | Milvus (analyzer) |
|---|---|---|
| 思想 | 找包含某个词的记录 | 找包含某个词的记录 |
| 实现方式 | 逐行扫描字符串 | 倒排索引 + 分词引擎 |
| 性能 | 慢(O(n)) | 快(O(log n) 或更快) |
| 智能程度 | 字符匹配(大小写敏感?看设置) | 支持分词、小写化、同义词扩展等 |
| 适用场景 | 小数据量 | 大数据量 + 高并发检索 |
注意事项
- 分析器不能添加到向量数据字段
# 错误示例 schema.add_field( field_name="vector", datatype=DataType.FLOAT_VECTOR, dim=1024, analyzer_params=analyzer_params_builtin ) - 动态字段默认不会启用 analyzer,也无法被全文检索引擎处理。除了向量数据,其他都是标量字段
标量字段 vs 动态字段
标量字段:指的是数据类型为 INT64、VARCHAR、ARRAY、JSON 等非向量字段。
动态字段:是一种灵活的数据写入机制,允许插入未定义的字段,这些字段最终会存入一个 JSON 标量字段中。
版权所有
版权归属:念宇
