一、基础环境准备与依赖安装
在开始搭建地震档案数字化系统之前,需要准备一台安装了Linux操作系统的服务器(推荐CentOS 7.9或Ubuntu 20.04)。本方案采用Docker容器化部署,确保环境隔离与快速交付。首先执行以下命令安装Docker及必要的系统工具。
1. 安装Docker与Docker Compose
执行以下脚本,一键安装Docker引擎及Compose插件,无需手动配置源:
```bash
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
systemctl start docker
systemctl enable docker
验证安装
docker --version
```
2. 创建项目目录结构
为了规范管理,建立如下目录结构用于存放配置、数据及Python脚本:
```bash
mkdir -p /data/seismic_archive/{data,scripts,logs,upload}
cd /data/seismic_archive
```
二、部署Elasticsearch搜索引擎
Elasticsearch是核心存储引擎,用于对地震档案的全文内容进行高性能检索。我们将直接使用Docker运行ES单节点模式,并配置内存参数以防止服务器资源耗尽。
1. 拉取并启动Elasticsearch容器
执行以下命令,拉取8.x版本镜像,并开放9200端口。注意-e "discovery.type=single-node"用于单机开发模式,-e "xpack.security.enabled=false=false"关闭安全认证以降低零门槛上手难度。
```bash
docker run -d \
--name es-archive \
--restart=always \
-p 9200:9200 \
-p 9300:9300 \
-e "discovery.type=single-node" \
-e "xpack.security.enabled=false" \
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
-v /data/seismic_archive/data/es_data:/usr/share/elasticsearch/data \
docker.elastic.co/elasticsearch/elasticsearch:8.11.0
```
2. 验证服务状态
等待约30秒让服务初始化,然后通过curl检查集群健康状态:
```bash
curl -u elastic:changeme http://localhost:9200/_cluster/health
```
如果返回JSON字符串中包含"status": "green"或"yellow",说明部署成功。
三、安装OCR文字识别环境
地震部门的历史档案多为扫描件PDF或图片,需要OCR技术将其转换为可检索的文本。这里使用Tesseract OCR引擎,它开源免费且支持中文识别。
1. 安装Tesseract引擎及中文语言包
针对不同系统执行对应的安装命令:
```bash
CentOS/RHEL
yum install -y tesseract tesseract-langpack-chi_sim
Ubuntu/Debian
apt-get update
apt-get install -y tesseract-ocr tesseract-ocr-chi-sim
```

2. 安装Python依赖库
我们需要Python脚本来连接ES并调用OCR接口。创建虚拟环境并安装依赖:
```bash
python3 -m venv /data/seismic_archive/venv
source /data/seismic_archive/venv/bin/activate
pip install elasticsearch pytesseract pdf2image Pillow requests
``>
注意:pdf2image2image依赖系统中的poppler-utils,若报错请执行apt-get install -y poppler-utils。
四、编写档案索引入库脚本
此脚本将/data/seismic_archive/upload目录下的PDF文件自动提取文字,并写入Elasticsearch。创建文件scripts/indexer.py:
```python
import os
import pytesseract
from pdf2image import convert_from_path
from elasticsearch import Elasticsearch
from datetime import datetime
配置ES连接
ES_HOST = "http://localhost:9200"
es = Elasticsearch(ES_HOST)
INDEX_NAME = "seismic_archives"
索引映射定义(如果不存在则创建)
def create_index():
if not es.indices.exists(index=INDEX_NAME):
mapping = {
"mappings": {
"properties": {
"file_name": {"type": "keyword"},
"file_path": {"type": "keyword"},
"content": {"type": "text", "analyzer": "standard"},
"upload_time": {"type": "date"},
"page_count": {"type": "integer"}
}
}
}
es.indices.create(index=INDEX_NAME, body=mapping)
print(f"索引 {INDEX_NAME} 创建成功")
提取PDF文字内容
def extract_text_from_pdf(pdf_path):
try:
将PDF转换为图片,每页一张图
pages = convert_from_path(pdf_path, dpi=200)
full_text = ""
for page in pages:
使用Tesseract识别中文,lang='chi_sim'
text = pytesseract.image_to_string(page, lang='chi_sim+eng')
full_text += text + "\n"
return full_text, len(pages)
except Exception as e:
print(f"OCR处理失败 {pdf_path}: {str(e)}")
return "", 0
遍历目录并入库
def process_directory(upload_dir):
create_index()
files = [f for f in os.listdir(upload_dir) if f.endswith('.pdf')]
for filename in files:
file_path = os.path.join(upload_dir, filename)
print(f"正在处理: {filename} ...")
检查是否已存在
res = es.search(index=INDEX_NAME, body={
"query": {"term": {"file_name": filename}},
"size": 1
})
if res['hits']['total']['value'] > 0:
print("文件已存在,跳过。")
continue
content, page_count = extract_text_from_pdf(file_path)
if not content:
continue
doc = {
"file_name": filename,
"file_path": file_path,
"content": content,
"upload_time": datetime.now(),
"page_count": page_count
}
es.index(index=INDEX_NAME, body=doc)
print(f"入库成功: {filename}, 页数: {page_count}")
if __name__ == "__main__":
upload_dir = "/data/seismic_archive/upload"
process_directory(upload_dir)
```
操作说明:将需要培训的地震档案PDF文件放入/data/seismic_archive/upload目录,然后运行脚本:
```bash
source /data/seismic_archive/venv/bin/activate
python /data/seismic_archive/scripts/indexer.py
```
五、实现档案检索查询功能
数据入库后,我们需要一个查询接口供培训系统调用。创建scripts/search.py,实现基于关键词的高亮检索。
```python
from elasticsearch import Elasticsearch
ES_HOST = "http://localhost:9200"
es = Elasticsearch(ES_HOST)
INDEX_NAME = "seismic_archives"
def search_archives(keyword, size=10):
"""
搜索地震档案内容
:param keyword: 搜索关键词,如 "地震预警"
:param size: 返回结果数量
"""
query_body = {
"query": {
"multi_match": {
"query": keyword,
"fields": ["file_name", "content"],
"type": "best_fields"
}
},
"highlight": {
"pre_tags": [""],
"post_tags": [""],
"fields": {
"content": {}
}
},
"size": size
}
try:
resp = es.search(index=INDEX_NAME, body=query_body)
hits = resp['hits']['hits']
print(f"找到 {resp['hits']['total']['value']} 条相关档案:\n")
for hit in hits:
source = hit['_source']
score = hit['_score']
print(f"【文件名】{source['file_name']} (相关度: {score:.2f})")
print(f"【路径】{source['file_path']}")
输出高亮片段
if 'highlight' in hit and 'content' in hit['highlight']:
highlights = hit['highlight']['content']
print("【摘要】...")
for h in highlights[:2]: 只显示前两段高亮
print(h.replace('\n', ' '))
print("-" 50)
except Exception as e:
print(f"搜索出错: {str(e)}")
if __name__ == "__main__":
示例:搜索包含"应急预案"的档案
search_archives("应急预案")
```
运行测试命令:
```bash
python /data/seismic_archive/scripts/search.py
``>
六、常见问题排查与优化
在实操过程中,可能会遇到以下具体问题,请按方案处理:
1. OCR识别速度慢或内存溢出
如果上传的PDF是大文件,pdf2image会生成大量高分辨率图片导致内存飙升。修改indexer.py中的convert_from_path参数,降低DPI:
```python
将dpi从200降至100,或使用first_page/last_page限制处理页数
pages = convert_from_path(pdf_path, dpi=100, thread_count=4)
```
2. Elasticsearch拒绝连接
检查Docker容器日志,通常是因为vm.max_map_count设置过低。在宿主机执行:
```bash
sysctl -w vm.max_map_count=262144
永久生效需修改 /etc/sysctl.conf
```
3. 中文分词搜索不准
默认Standard分词器对中文支持一般(按字拆分)。如需按词语搜索(如将“地震监测”拆为一个词),需安装IK分词器。在Docker启动命令中添加插件安装参数:
```bash
进入容器安装
docker exec -it es-archive /bin/bash
elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v8.11.0/elasticsearch-analysis-ik-8.11.0.zip
退出并重启容器
exit
docker restart es-archive
```
安装后,需将索引映射中的"analyzer": "standard"修改为"analyzer": "ik_max_word"并重建索引。