N1ql加入并聚合其他值

问题描述 投票:1回答:1

我有一个包含以下文档的存储桶(Couchbase社区版本6.5):

employees {
    employeeGroupId: string,
    type: "Employee"
}
clocks {
    employeeId: string,
    areaId: string
    date: string,
    type: "Clock"
}

每个员工每天都有多个相应的时钟项目。我需要获得以下信息:

  1. 第一个时钟-> clockIn
  2. 最后一个时钟-> clockOut

我编写了以下查询,该查询获取执行时间<100 ms的第一个和最后一个时钟项:

SELECT META(employee).id AS employeeId,
       employee.employeeGroupId,
       MIN(clock.date) AS clockIn,
       MAX(clock.date) AS clockOut
FROM `bucket` employee LEFT
    JOIN `bucket` clock ON clock.employeeId = META(employee).id
    AND type = "Clock"
    AND clock.date BETWEEN "2020-06-01T00:00:00.000Z" AND "2020-06-02T00:00:00.000Z"
WHERE employee.type = "Employee"
GROUP BY employee;

问题是我需要获取具有匹配时钟的相应areaId。

我已经编写了以下查询。我创建了两个单独的子查询,它们对当天的所有时钟项进行了排序,先升后降,然后选择第一项。

CREATE INDEX adv_employeeId_type_date_blockId ON `bucket`(`employeeId`,`type`,`date`,`blockId`)        
CREATE INDEX adv_employeeId_type_date ON `bucket`(`employeeId`,`type`,`date`)
CREATE INDEX adv_type_employeeId_date ON `bucket`(`type`,`employeeId`,`date`)

SELECT META(employee).id AS employeeId,
       employee.employeeGroupId,
       clockIn,
       clockOut
FROM `bucket` employee 
    LEFT JOIN (
    SELECT obj.employeeId,
           obj.date,
           obj.areaId
    FROM `bucket` obj
    WHERE obj.employeeId = META(employee).id
        AND obj.type = "Clock"
        AND obj.date BETWEEN "2020-06-01T00:00:00.000Z" AND "2020-06-02T00:00:00.000Z"
    ORDER BY obj.date
    LIMIT 1) clockIn ON clockIn.employeeId = META(employee).id 
    LEFT JOIN (
    SELECT obj.employeeId,
           obj.date,
           obj.areaId
    FROM `bucket` obj
    WHERE obj.employeeId = META(employee).id
        AND obj.type = "Clock"
        AND obj.date BETWEEN "2020-06-01T00:00:00.000Z" AND "2020-06-02T00:00:00.000Z"
    ORDER BY obj.date DESC
    LIMIT 1) clockOut ON clockOut.employeeId = META(employee).id
WHERE employee.type = "Employee"
GROUP BY employee,
         clockIn,
         clockOut;

问题是上述查询在执行时间> 10秒时效率低下。

换句话说,我需要从聚合的MIN()和MAX()函数中获取其他对象值。

我确信第二个查询不是实现此目的的最有效方法,有人有其他建议吗?

performance join couchbase n1ql
1个回答
0
投票
CREATE INDEX ix1 ON `bucket`(type, `employeeGroupId`) WHERE type = "Employee";
CREATE INDEX ix2 ON `bucket`(`employeeId`, date, areaId) WHERE type = "Clock";

SELECT META(employee).id AS employeeId,
       employee.employeeGroupId,
       minclock[0] AS clockIn,
       minclock[1] AS clockInAreaId,
       maxclock[0] AS clockOut,,
       maxclock[1] AS clockOutAreaId
FROM `bucket` AS employee LEFT
    JOIN `bucket` AS clock ON clock.employeeId = META(employee).id
    AND type = "Clock"
    AND clock.date BETWEEN "2020-06-01T00:00:00.000Z" AND "2020-06-02T00:00:00.000Z"
WHERE employee.type = "Employee"
GROUP BY employee
LETTING minclock = MIN([clock.date,clock.areaId]),
        maxclock = MAX([clock.date,clock.areaId]);

在阵列上使用MIN / MAX。 MIN / MAX上的第0个表达式。重置仅在平局上使用的数组位置(类似于ORDER BY多个字段)。结果将完成ARRAY表达式。选择您想要的职位。此技术使您可以按表达式投影非分组。

© www.soinside.com 2019 - 2024. All rights reserved.