如何在elasticsearch-dsl保存Document前移除未定义字段?
解决elasticsearch-dsl过滤未定义字段的问题
针对你的需求,有几种可行的解决方案,包括利用elasticsearch-dsl的特性和自定义处理逻辑:
1. 初始化前手动过滤字段
在创建MyDoc实例前,直接筛选出输入字典中属于类已定义字段的键值对:
# 仅保留MyDoc中声明过的字段 filtered_doc = {k: v for k, v in doc.items() if k in MyDoc._fields} my_doc = MyDoc(**filtered_doc) my_doc.save()
MyDoc._fields会返回类中所有已定义字段的名称集合,这种方式简单直接,适合单次场景使用。
2. 重写类构造方法自动过滤
如果需要全局自动过滤未知字段,可以重写MyDoc的__init__方法,在实例化时自动剔除未定义的字段:
class MyDoc(Document): name = Text() age = Integer() course = Keyword() class Index: name = "test-index" def __init__(self, **kwargs): # 过滤掉不在已定义字段列表中的键 filtered_kwargs = {k: v for k, v in kwargs.items() if k in self._fields} super().__init__(**filtered_kwargs) # 直接传入原始字典即可自动过滤unknown字段 doc = {"name": "John Doe", "age": "3", "unknown": "yes"} my_doc = MyDoc(**doc) my_doc.save()
这种方式一劳永逸,所有创建MyDoc实例的场景都会自动处理未知字段。
3. 利用prepare钩子预处理
elasticsearch-dsl提供的prepare方法会在文档序列化前执行,可以在这里完成字段过滤:
class MyDoc(Document): name = Text() age = Integer() course = Keyword() class Index: name = "test-index" def prepare(self): # 获取原始待序列化数据 data = super().prepare() # 过滤掉未定义字段后返回 return {k: v for k, v in data.items() if k in self._fields} doc = {"name": "John Doe", "age": "3", "unknown": "yes"} my_doc = MyDoc(**doc) my_doc.save()
prepare方法返回的字典就是最终存入Elasticsearch的数据,通过这里过滤能确保未知字段不会被写入索引。
内容的提问来源于stack exchange,提问作者Mwangi Kabiru
相关产品推荐
相关产品推荐

