【问题标题】:How to join two Document objects in elasticsearch-dsl?如何在 elasticsearch-dsl 中加入两个 Document 对象?
【发布时间】:2019-09-03 11:57:14
【问题描述】:

我正在尝试使用 elasticsearch-dsl 在两个索引文档之间创建“关系”。当使用Object(EsPerson) 作为EsComment 的字段时。当我更新EsPerson 时,EsComment 中的字段不会更新。

我尝试过使用 InnerDoc,但它没有被索引,也没有更新

class EsPersonAttr(InnerDoc):
    id = Long(required=True)
    name = Text(fields={'keyword': Keyword()}, required=True)

    def __repr__(self):
        return '<EsPersonAttr: {}>'.format(
            self.name,
        )

class EsPersonIndex(Document):
    """
    Elastic Search Person model.
    """
    class Index:
        name = 'es-person'

    class meta:
        doc_type = 'es-person'

    id = Long(required=True)
    name = Text(fields={'keyword': Keyword()}, required=True)

    def save(self, **kwargs):
        return super(EsPersonIndex, self).save(**kwargs)

    def __repr__(self):
        return '<EsPersonIndex: {}>'.format(
            self.name,
        )


class EsPerson(object):
    def __init__(self, id, name):
        self._id = id
        self._name = name

        self.index_doc = EsPersonIndex(
            id=id,
            name=name
        )

        self.attr_doc = EsPersonAttr(
            id=id,
            name=name
        )

    def __repr__(self):
        return '<EsPerson: {}>'.format(
            self._name,
        )

    @property
    def id(self):
        return self._id

    @id.setter
    # Set both Document & InnerDoc at the same time
    def id(self, value):
        self._id = value

        # self.index_doc.id = value
        self.index_doc.update()

        self.attr_doc.id = value

    @property
    def name(self):
        return self._id

    @name.setter
    # Set both Document & InnerDoc at the same time
    def name(self, value):
        self._name = value

        self.index_doc.name = value
        self.index_doc.save()

        self.attr_doc.name = value


class EsComment(Document):
    """
    Elastic Search Comment model.
    """
    id = Long(required=True)
    title = Text(fields={'keyword': Keyword()}, required=True)
    text = Text(fields={'keyword': Keyword()})
    author = Object(EsPersonAttr, required=True)

    class Index:
        name = 'es-comment'

    class meta:
        doc_type = 'es-comment'

    def save(self, **kwargs):
        # if there is no date, use now
        return super(EsComment, self).save(**kwargs)

    def __repr__(self):
        return '<EsComment: {}>'.format(
            self.title,
        )

我希望当我更新 EsPerson 的名称字段时,它会更新 EsComment 中的 author.name

【问题讨论】:

    标签: python python-3.x elasticsearch-dsl


    【解决方案1】:

    您可能想看一下使用parent/childnested 的示例,它们是Elasticsearch 中连接对象的两种方法:https://github.com/elastic/elasticsearch-dsl-py/blob/master/examples/parent_child.py

    【讨论】:

    • Join(relations={'question': 'answer'}) 中字典中与索引名称相关的字符串。所以在我的例子中它是Join(relations={'es-comment': 'es-person'})。它们是否需要是同一个父对象的子类,例如Post
    • 不是索引名称,只是作为父级和子级的文档的“类型”。它们不必是子类,但因为它们最终需要在同一个索引中,因此可能共享一堆字段,这是一种更简单、更直接的方法
    猜你喜欢
    • 1970-01-01
    • 2016-01-24
    • 1970-01-01
    • 1970-01-01
    • 2016-10-16
    • 1970-01-01
    • 2017-03-09
    • 2017-05-05
    • 2017-07-03
    相关资源
    最近更新 更多