之前用Elasticsearch进行数据查询的方式很少,最近在进行Elasticsearch相关的查询操作。这里记录一下如何使用python语言,将PostgreSQL数据库中的数据同步到Elasticsearch中,方便进行高效的查询。
Elasticsearch与PostgreSQL对比
Elasticsearch与PostgreSQL是两种不同类型的数据库,它们各自有其特点和适用场景。以下是它们的一些对比:
- 数据存储方式:
- Elasticsearch:Elasticsearch是一个基于Lucene的全文搜索引擎,它将数据索引以便快速搜索。它不是传统的关系数据库,不支持ACID事务。
- PostgreSQL:PostgreSQL是一个关系型数据库管理系统(RDBMS),遵循ACID模型,支持复杂的SQL查询和事务。
- 数据结构和类型:
- Elasticsearch:Elasticsearch使用JSON文档,但它有自己的数据结构,如字段映射和内部索引。
- PostgreSQL:PostgreSQL使用SQL表来存储数据,并且可以定义复杂的数据类型和关系。
- 性能和可扩展性:
- Elasticsearch:Elasticsearch通过分布式架构提供极致的可扩展性,能够处理大量的数据。
- PostgreSQL:PostgreSQL也支持高可扩展性,通过分片和复制可以扩展数据库。
- 查询和分析能力:
- Elasticsearch:Elasticsearch专注于全文搜索和分析,拥有强大的全文搜索和聚合功能。
- PostgreSQL:PostgreSQL拥有强大的SQL查询和复杂分析功能,包括复杂的连接、窗口函数和聚合查询。
- 成熟度和社区支持:
- Elasticsearch:Elasticsearch拥有成熟的生态系统和广泛的社区支持。
- PostgreSQL:PostgreSQL有着成熟的生态系统和广泛支持,并且在数据一致性和安全性方面有着丰富的经验。
- 定价和许可:
- Elasticsearch:Elasticsearch是开源免费的,但需要自己维护。
- PostgreSQL:PostgreSQL有开源免费版本,也有商业版本,需要根据需求选择。
选择哪种数据库取决于具体需求,如数据类型、查询要求、可扩展性、成本等。在某些情况下,可以将Elasticsearch与PostgreSQL结合使用,以利用它们各自的优势。
同步数代码
# pip install elasticsearch7.10.1
from elasticsearch import Elasticsearch, helpers
import psycopg2
import json
from datetime import datetime
# 连接PostgreSQL数据库
conn = psycopg2.connect(
dbname="postgres",
user="postgres",
password="postgresql",
host="192.168.1.2"
)
cur = conn.cursor()
# 从数据库查询数据
cur.execute("SELECT arealevel,coid,env,qhdm,qhmc,null as type ,to_char(updatetime,'yyyy-MM-dd HH:mm:ss') as "
"updatetime FROM sys_area limit 1000000")
rows = cur.fetchall()
def delete_index(es, index_name):
"""
删除索引
:param es: Elasticsearch对象
:param index_name: 索引名称
:return:
"""
if es.indices.exists(index=index_name):
# 删除索引
response = es.indices.delete(index=index_name)
print(response)
def create_index(es, index_name, body):
"""
创建索引
:param es: Elasticsearch对象
:param index_name: 索引名称
:return:
"""
if not es.indices.exists(index=index_name):
# 创建索引
index_name = index_name
response = es.indices.create(index=index_name, body=body)
print(response)
if __name__ == '__main__':
actions = []
v_lens = 0
# 连接到Elasticsearch
es = Elasticsearch("http://192.168.1.2:9200")
delete_index(es, "sys_area")
body = {
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
},
"mappings": {
"properties": {
"arealevel": {
"type": "text", "fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"coid": {
"type": "text", "fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"env": {
"type": "text", "fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"qhdm": {
"type": "text", "fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"qhmc": {
"type": "text", "fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"type": {
"type": "text", "fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"updatetime": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
}
}
}
}
create_index(es, "sys_area", body)
for row in rows:
action = {
"_index": "sys_area",
"_id": row[3], # 假设第一列是ID
"_source": {
"arealevel": row[0],
"coid": row[1],
"env": row[2],
"qhdm": row[3],
"qhmc": row[4],
"type": row[5],
"updatetime": row[6]
}
}
actions.append(action)
if len(actions) == 1000:
v_lens += len(actions)
print('========已处理1000条数据,开始发送es=======')
helpers.bulk(es, actions)
del actions[0:len(actions)]
# 使用helpers库进行数据同步
v_lens += len(actions)
if v_lens > 0:
print('========开始发送最后' + str(len(actions)) + '条数据到es=======')
helpers.bulk(es, actions)
print('========合计发送' + str(v_lens) + '条数据到es=======')
# 关闭数据库连接
cur.close()
conn.close()