Elasticsearch与Python

最近在python项目中操作es,有些问题需要记录一下:

1,一般会使用elastic Kibana 使用命令去操作es,但是es不像mysql那样,可以快速导入导出,做数据恢复,如果把某个index删掉了,或者弄坏了,那么需要很长的恢复时间,甚至恢复不了,所以使用命令行的时候要格外小心,我通过下面的几个步骤来尽量规避风险:

     a,命令执行前,再次检查链接的环境

     b,在生产环境,执行任何命令前,都应该在测试环境先执行一遍,检查该,命令是否满足了语义。POST/DELETE  都可能改写index,在执行前都要去测试环境提前执行一遍。

特别是DELETE语句,有的时候,我们可能想立刻删除掉线上的某条数据(在页面没有删除按钮),如果漏了后面的id,将会删除整个index,最好先在测试环境,找到对应的index去操作一遍,最后再select count(*)  from index 下,看看是否真的只删掉了这一条。

# 步骤一:现在测试环境执行查询语句
POST test_index_dev/_search
{
 "query": {
        "bool": {
            "must": [
                {
                 "match": {
                        "name": "laibincs"
                    }
                }
            ]
        }
}

}


# 步骤二:正确的按照id删除
DELETE test_index_dev/_doc/jsjhdgxhhhd90998


# 步骤三:再次执行步骤一,检查数据是否存在

# 步骤四:检查总数是否只减少了1

# 步骤五:都正确的情况下,再去操作生产环境

不要觉得麻烦,一定要严格遵守。

2,建议在python中使用elasticsearch_dsl来链接es,有通用的模式:

from elasticsearch_dsl import Q
from elasticsearch_dsl import Text, Document, Date, Keyword
from elasticsearch_dsl.connections import connections

elasticsearch = connections.create_connection(hosts=conf.ELASTICSEARCH_HOSTS,
                                              http_auth=(conf.ELASTICSEARCH_USERNAME, conf.ELASTICSEARCH_PASSWORD))


class UserDocument(Document):
    user_name = Keyword()
    user_age = Keyword()
    user_context = Text(analyzer="ik_max_word", search_analyzer="ik_smart")
    create_time = Date()

    class Index:
        name = "es_user_index"


class EsUserDao:
    userDocument = None

    def __init__(self):
        self.userDocument = UserDocument()

    def search(self):
        return self.userDocument.search()

    def save_one(self, user_document):
        # refresh 变量控制新保存的数据,是否立刻刷新,保证下次查询立刻可见
        user_document.save(refresh=True)

    def delete_by_doc_ids(self, doc_ids):
        self.search() \
            .filter("ids", values=doc_ids) \
            .delete()

    def find_one_by_doc_id(self, doc_id):
        return self.userDocument.get(id=doc_id)
     
    # highlight_fields = ["name","user_context"]
    def find_by_condition(self, request):
        search = self.search()

        # 准确查询
        if request.name is not None:
            search = search.query("bool", must=[Q("term", name=request.name)])

        # 关键词高亮查询
        if request.keyword is not None:
            search = search.query("multi_match", query=request.keyword, fields=request.highlight_fields)
            search = search.highlight(*tuple(request.highlight_fields), fragment_size=50)

        if request.age is not None:
            search = search.query("bool", must=[Q("term", age=request.age)])

        # 范围查询
        if request.create_time is not None:
            search = search.query('range', create_time={'gte': request.min_time, 'lte': request.max_time})

        # 分页与排序
        rp = search \
            .source(["name", "age"]) \
            .extra(from_=request.from_index, size=request.page_size) \
            .sort({"create_time": {"order": "desc"}}) \
            .execute()

        return rp
    
    # 根据id更新   update_content = {"name": "change_new_name"}
    def update_by_id(self, report_id, update_content):
        elasticsearch.update(index=conf.REPORT_INDEX, id=report_id, body={"doc": update_content})


if __name__ == '__main__':
    UserDocument.init()

a, 创建一个链接

b,python中的class需要继承自Document

c,在内部定义一个Index类,name指明对应es的index。

d,建立一个新的Dao类来提供增删改的接口

需要注意高亮显示那里,有的时候,我们的查询条件可能是 name ="laibin" and keyword ="laibin"

假如数据库中,有一个doc满足  user_context 中含有"laibin"且 name =''laibincs'的情况下,es也会把name当作高亮显示,但这是不对的,需要做判断

3,缺少python对es去重或者分组查询的。后续补上。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值