elasticsearch,Python,elasticsearch" /> elasticsearch,Python,elasticsearch" />

Python 为每个父对象获取具有最大值的子对象

Python 为每个父对象获取具有最大值的子对象,python,elasticsearch,Python,elasticsearch,我已经创建了一个带有父子join数据类型的映射。 我希望在单个查询中获得每个父项的最大值的子项 可能吗?我试过一些方法,比如内部点击次数定义和聚合,比如顶部点击次数,子项,有父项和有子项 我的映射基于中的类Post、Question和Answer 使用elasticsearch_dsl代码的解决方案会很好,但简单的elasticsearch查询也会有所帮助 谢谢:) 编辑:我附上我的代码,希望它能有所帮助 classLoggerLogBase(基于classPost): class记录器(基于c

我已经创建了一个带有父子
join
数据类型的映射。 我希望在单个查询中获得每个父项的最大值的子项

可能吗?我试过一些方法,比如
内部点击次数
定义和聚合,比如
顶部点击次数
子项
有父项
有子项

我的映射基于中的类
Post
Question
Answer

使用elasticsearch_dsl代码的解决方案会很好,但简单的elasticsearch查询也会有所帮助

谢谢:)

编辑:我附上我的代码,希望它能有所帮助

class
LoggerLogBase
(基于class
Post
):

class
记录器
(基于class
问题
):

课堂
日志
(基于课堂
答案
):


我当前的解决方案是为每个记录器调用
logger.search\u latest\u log()
,但它需要N个查询。我希望能够在单个查询中执行此操作,以提高此操作的性能。

我认为您的解决方案是和的混合:


让我知道它是否工作或发生了任何问题;-)接得好,很管用!(如果将“name.keyword”更改为“name”。我不喜欢“top Logger”中的“terms”查询,但我想我会找到更好的方法来处理这个问题(我还想添加一些条件,所以我想我会从这里找到一种方法)。谢谢!
class LoggerLogBase(Document):
    """
    A base class for :class:`~data_classes.Log` and :class:`~data_classes.Logger` data classes.
    """

    logger_log = Join(relations={'logger': 'log'})

    @classmethod
    def _matches(cls, hit):
        """
        Returns whether a hit matches this class or not.
        """
        return False

    class Index:
        """
        Meta-class for defining the index name.
        """
        name = 'logger-log'
class Logger(LoggerLogBase):
    """
    A class to represent a temperature logger.
    """
    name = Keyword()
    display_name = Keyword()
    is_displayed = Boolean()

    @classmethod
    def _matches(cls, hit):
        """
        Returns whether a hit matches this class or not.
        """
        return hit['_source']['logger_log'] == 'logger'

    @classmethod
    def search(cls, **kwargs):
        """
        Creates an :class:`~elasticsearch_dsl.Search` instance that will search
        over this index.
        """
        return cls._index.search(**kwargs).filter('term', logger_log='logger')

    def add_log(self, timestamp, heat_index_celsius, humidity, temperature_celsius):
        """
        Save a new log which was logged by this logger.
        """
        log = Log(
            _routing=self.meta.id,
            logger_log={'name': 'log', 'parent': self.meta.id},
            timestamp=timestamp,
            heat_index_celsius=heat_index_celsius,
            humidity=humidity,
            temperature_celsius=temperature_celsius
        )

        log.save()
        return log

    def search_logs(self):
        """
        Returns the search for this logger's logs.
        """
        search = Log.search()
        search = search.filter('parent_id', type='log', id=self.meta.id)
        search = search.params(routing=self.meta.id)
        return search

    def search_latest_log(self):
        """
        Returns the search for this logger's latest log.
        """
        search = self.search_logs()\
                        .params(size=0)
        search.aggs.metric('latest_log',
                           'top_hits',
                           sort=[{'timestamp': {'order': 'desc'}}],
                           size=1)
        return search

    def save(self, using=None, index=None, validate=True, **kwargs):
        """
        Saves the document into elasticsearch.
        See documentation for elasticsearch_dsl.Document.save for more information.
        """
        self.logger_log = {'name': 'logger'}
        return super().save(using, index, validate, **kwargs)
class Log(LoggerLogBase):
    """
    A class to represent a single temperature measurement log.
    """
    timestamp = Date()
    heat_index_celsius = Float()
    humidity = Float()
    temperature_celsius = Float()

    @classmethod
    def _matches(cls, hit):
        """
        Returns whether a hit matches this class or not.
        """
        return isinstance(hit['_source']['logger_log'], dict) \
            and hit['_source']['logger_log'].get('name') == 'log'

    @classmethod
    def search(cls, using=None, **kwargs):
        """
        Creates an :class:`~elasticsearch_dsl.Search` instance that will search
        over this index.
        """
        return cls._index.search(using=using, **kwargs).exclude('term', logger_log='logger')

    @property
    def logger(self):
        """
        Returns the logger that logged this log.
        """
        if 'logger' not in self.meta:
            self.meta.logger = Logger.get(id=self.logger_log.parent, index=self.meta.index)
        return self.meta.logger

    def save(self, using=None, index=None, validate=True, **kwargs):
        """
        Saves the document into elasticsearch.
        See documentation for elasticsearch_dsl.Document.save for more information.
        """
        self.meta.routing = self.logger_log.parent
        return super().save(using, index, validate, **kwargs)
POST logger-log/_search?size=0
{
  "aggs": {
    "top-loggers": {
      "terms": {
        "field": "name"
      },
      "aggs": {
        "to-logs": {
          "children": {
            "type" : "log" 
          },
          "aggs": {
            "top-logs": {
              "top_hits": {
                    "size": 1,
                    "sort": [
                        {
                            "timestamp": {
                                "order": "desc"
                            }
                        }
                    ]
                }
            }
          }
        }
      }
    }
  }
}