导读:本期聚焦于星河创作的《如何用SQLite结合HanLP打造一个轻量级中文自然语言处理系统?》,敬请观看详情。为什么要在SQLite里做中文自然语言处理?当你面对的是单机部署、数据量不大但又需要快速检索和语义分析的场景时,SQLite加上HanLP的组合几乎是最省事的选择。SQLite作为嵌入式数据库零配置、免维护,HanLP则提供了分词、词性标注、命名实体识别、关键词提取等完整的中文处理能力。本文将从环境搭建讲起,演示如何在Python或Java中调用HanLP完成分词并写入SQLite,再介绍如何利用SQLite的FTS5全文索引配合分词结果实现高效的中文搜索,最后给出一个新闻文本分析实战案例,涵盖数据入库、倒排索引构建与相似度查询,帮助你理解这套轻量方案的能力边界与落地细节。

做中文文本处理,很多团队第一反应是上Elasticsearch或者MongoDB,但如果你的数据量在百万级以内、部署环境只有一台服务器甚至一台笔记本,这套重型方案就显得杀鸡用牛刀了。SQLite作为全球使用最广的嵌入式数据库,单个文件就是一个完整数据库,配合HanLP提供的中文分词、命名实体识别和关键词提取能力,完全可以搭建一套零运维的文本分析系统。这篇文章就带大家把这个组合真正跑起来。

如何用SQLite结合HanLP打造一个轻量级中文自然语言处理系统?

为什么是SQLite加HanLP而不是别的组合

先说SQLite这一端。它是一个纯C实现的嵌入式关系型数据库,整个数据库就是磁盘上的一个文件,不需要单独的数据库服务进程,也不需要配置账号密码。Python、Java、Go等主流语言都内置或者提供了成熟的驱动。对于文本分析场景,SQLite还有一个杀手锏:FTS5全文检索扩展,它支持倒排索引、自定义分词器、BM25相关性排序,功能上覆盖了搜索引擎最核心的部分。

再看HanLP。它是纯Java实现的中文自然语言处理库,同时通过pyhanlp提供了Python接口。HanLP内置了分词、词性标注、命名实体识别、依存句法分析、关键词提取、文本摘要等常用功能,词典和模型开箱即用,不需要自己训练。相比jieba这类轻量分词工具,HanLP在准确率和功能完整度上明显更强,尤其是对地名、机构名、人名的识别能力,在处理新闻类文本时差距非常明显。

两者组合的典型架构是:HanLP负责把非结构化的中文文本转换成结构化的分词结果和实体信息,SQLite负责存储这些结构化数据并建立索引。整个系统不依赖任何外部服务,把数据库文件拷走就等于完成了迁移,这在做内网部署、离线分析工具或者个人知识库项目时特别实用。

环境搭建与基础分词入库

环境搭建分两步。第一步安装HanLP,Python环境推荐用pyhanlp,它要求JRE环境,因为底层是Java实现。第二步确认Python自带的sqlite3模块可用,这个标准库模块直接就能操作SQLite,无需额外安装。

安装命令如下:

# 安装pyhanlp,需要本机有Java运行环境
pip install pyhanlp

# 验证安装
python -c "from pyhanlp import HanLP; print(HanLP.segment('你好,欢迎使用SQLite与HanLP'))"

接下来做最核心的一件事:把一段文本分词后写入SQLite。设计上建议建两张表,一张存原始文档,一张存分词结果,分词结果表以词为单位建立记录,方便后续按词聚合统计。建表语句如下:

-- 原始文档表
CREATE TABLE IF NOT EXISTS documents (
    doc_id INTEGER PRIMARY KEY AUTOINCREMENT,
    title TEXT NOT NULL,
    content TEXT NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- 分词结果表,term存词语,nature存词性
CREATE TABLE IF NOT EXISTS tokens (
    token_id INTEGER PRIMARY KEY AUTOINCREMENT,
    doc_id INTEGER NOT NULL,
    term TEXT NOT NULL,
    nature TEXT,
    FOREIGN KEY (doc_id) REFERENCES documents(doc_id)
);

-- 按词建立索引,加速后续查询
CREATE INDEX IF NOT EXISTS idx_tokens_term ON tokens(term);

分词入库的Python代码可以这样写:

import sqlite3
from pyhanlp import HanLP, JClass

# 去掉停用词、只保留名词和动词的简单过滤
def extract_terms(text):
    terms = []
    for term in HanLP.segment(text):
        nature = str(term.nature)
        if nature.startswith('n') or nature.startswith('v'):
            terms.append((str(term.word), nature))
    return terms

conn = sqlite3.connect('corpus.db')
cur = conn.cursor()

doc_text = '中国科学技术大学的研究团队在量子计算领域取得新突破。'
cur.execute('INSERT INTO documents (title, content) VALUES (?, ?)',
            ('量子计算新突破', doc_text))
doc_id = cur.lastrowid

cur.executemany('INSERT INTO tokens (doc_id, term, nature) VALUES (?, ?, ?)',
                [(doc_id, t, n) for t, n in extract_terms(doc_text)])
conn.commit()
conn.close()

这段代码里有个细节值得注意:词性过滤用startswith('n')可以把名词大类(普通名词、地名、机构名、人名等)全部保留下来,这是控制入库词条数量的第一道闸门。如果不做过滤,一篇文档动辄几百个词条,其中虚词占了大量空间,对检索和统计几乎没有价值。

用FTS5打造高性能中文全文检索

把分词结果拆成一条条记录存进tokens表固然灵活,但查询效率会成为瓶颈,尤其是做AND查询时需要多次回表。更优雅的方案是使用SQLite的FTS5虚拟表,它内部维护倒排索引,查询性能和功能都远超手写方案。

FTS5默认按空白符分词,对中文不友好,解决办法是空间换逻辑:先用HanLP把文本分好词,词与词之间用空格拼接,再写入FTS5表。查询时同样把查询语句分词后用空格拼接。完整示例如下:

import sqlite3
from pyhanlp import HanLP

def tokenize_with_space(text):
    # HanLP分词后用空格连接,供FTS5使用
    words = [term.word for term in HanLP.segment(text)]
    return ' '.join(words)

conn = sqlite3.connect('corpus.db')
cur = conn.cursor()

# 创建FTS5虚拟表,不使用内置分词器
cur.execute("CREATE VIRTUAL TABLE IF NOT EXISTS doc_fts USING fts5(title, content)")

def add_document(title, content):
    cur.execute('INSERT INTO doc_fts (title, content) VALUES (?, ?)',
                (tokenize_with_space(title), tokenize_with_space(content)))

add_document('量子计算新突破', '中国科学技术大学的研究团队在量子计算领域取得新突破。')

def search(query, limit=10):
    q = tokenize_with_space(query)
    # 使用bm25排序,越靠前相关性越高
    sql = """SELECT title, content, bm25(doc_fts) AS score
             FROM doc_fts WHERE doc_fts MATCH ?
             ORDER BY score LIMIT ?"""
    for row in cur.execute(sql, (q, limit)):
        print(row)

search('量子计算 研究团队')
conn.commit()
conn.close()

这个方案有几个优势。第一,bm25函数直接给出相关性得分,省去了自己实现排序算法的工作;第二,FTS5支持NEAR、OR、NOT等丰富的查询语法,可以表达相当复杂的检索意图;第三,倒排索引的查询复杂度和词条数量基本无关,数据量涨到几十万条时检索仍然在毫秒级。

代价也不是没有。FTS5表会把分词结果再存一份,磁盘占用大约是原文的两到三倍。另外每次写入都要先调HanLP分词,写入吞吐量取决于分词速度,如果是批量导入场景,建议先把全部分词结果算好再统一执行executemany,配合with conn:语句批量提交事务,速度能快一个数量级。

实战:新闻文本的实体统计与相似文章查询

把前面的基础能力组合起来,就能做一个实用的小型文本分析系统。这里演示两个典型需求:统计一段时间内出现频次最高的命名实体,以及找出与某篇文章最相似的若干篇文档。

第一个需求直接基于tokens表做聚合。HanLP的命名实体识别在标准分词模型中已包含,机构名的词性是nt,地名是ns,人名是nr。统计SQL和Python代码如下:

import sqlite3

conn = sqlite3.connect('corpus.db')
cur = conn.cursor()

# 统计出现次数最多的10个机构名
rows = cur.execute("""
    SELECT term, COUNT(*) AS cnt
    FROM tokens
    WHERE nature = 'nt'
    GROUP BY term
    ORDER BY cnt DESC
    LIMIT 10
""").fetchall()

for term, cnt in rows:
    print(f'{term}: {cnt}次')
conn.close()

第二个需求用关键词提取加FTS5来完成。先用HanLP的extractKeyword从目标文章中提取出若干关键词,把它们拼成MATCH查询去检索相似文档。由于关键词本身就是文章语义的浓缩,这种伪相似度检索在实际效果上出奇地好:

import sqlite3
from pyhanlp import HanLP

def find_similar(content, top_n=5):
    # 提取文章核心关键词
    keywords = HanLP.extractKeyword(content, 10)
    query = ' OR '.join(keywords)

    conn = sqlite3.connect('corpus.db')
    cur = conn.cursor()
    rows = cur.execute("""
        SELECT title, bm25(doc_fts) AS score
        FROM doc_fts
        WHERE doc_fts MATCH ?
        ORDER BY score LIMIT ?
    """, (query, top_n)).fetchall()
    conn.close()
    return rows

# usage: find_similar('量子计算研究取得进展……')

这套方案的能力边界也要说清楚。SQLite的写并发只有单写多读,如果系统需要多个进程同时高频写入,就得引入写队列或者改用客户端服务器架构的数据库;HanLP的完整模型内存占用在1GB上下,低配机器上要留意;FTS5不支持分布式,数据量超过千万级文档时再考虑迁移到专门的搜索引擎。但只要场景在单机、千万级以下这个区间,SQLite加HanLP这套组合的开发效率和运行稳定性,绝对对得起它的轻量身材。

SQLiteHanLP自然语言处理修改时间:2026-09-05 02:08:40

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260905/50609.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。