为N1QL查询中的多个过滤条件组合创建Couchbase索引

时间:2019-06-11 10:47:49

标签: indexing couchbase n1ql

我们有两种类型的文档, CS 和//,当所有可选过滤器都位于同一个存储桶中时,我们使用 latestCommandStatusId 字段将两者合并> PCI ,它是 CS 文档的 id ,以及N1QL中的多个可选字段和一些必填字段。生产服务器上的响应时间太长,超过5-6秒,我们需要将其减少到300毫秒以下。

我们在同一存储桶中有两种文档,CS和PCI,我们使用PCI的LatestCommandStatusId字段(这是CS文档的ID)以及N1QL中的多个可选字段和一些必填字段将两者结合在一起。

CS(id = request10)
{
  "id": "request10",
  "_class": "CS",
  "status": "FAILED"
}


PCI(id = pci1)
{
  "id": "pci1",
  "latestCommandStatusId": "request10",  // equal to some CS doc id
  "_class": "PCI",
  "createdDateTime": 1672531200000,
  "effectiveDateTime": 1688083200000,
  "locationDSL": {
    "parameters": {
      "locationClusterId": ["L3", "L1","L2"]
    }
  },
  "productDSL": {
    "parameters": {
      "tpnb": ["02","04"]
    }
  }
}

现在要加入这些文档,我们有以下查询,该查询工作正常,但在具有巨大数据集的生产服务器中花费的时间太长。我的问题是,为了缩短以下过滤器组合的响应时间,我们需要创建哪些索引

SELECT  META(pci).id AS _ID,META(pci).cas AS _CAS, pci,cs
FROM prices pci JOIN prices cs ON KEYS pci.latestCommandStatusId   // join CS and PCI on pci.latestCommandStatusId which is id of CS doc
WHERE pci.effectiveDateTime BETWEEN "some_from_time" AND "some_to_time"   // compulsory filter 
AND 'some_tpnb' IN pci.productDSL.parameters.tpnb   // optional filter if some_tpnb is null in request param
AND 'some_locationClusterId' IN pci.locationDSL.parameters.locationClusterId   // optional filter if some_locationClusterId is null in request param
AND  pci.state = "some_pci_state"  // optional filter if some_pci_state is null in request param
AND cs.status = "some_cs_status"   // optional filter if some_cs_status is null in request param
ORDER BY pci.effectiveDateTime DESC  //mandatory ordering by pci.effectiveDateTime DESCending order
OFFSET 0 LIMIT 15   // mandatory pagination

因此,根据输入,我们有一些强制性过滤器和一些可选过滤器

例如,如果所有可选过滤器均为空

WHERE pci.effectiveDateTime BETWEEN "some_from_time" AND "some_to_time"   // compulsory filter 
ORDER BY pci.effectiveDateTime DESC  //mandatory ordering by pci.effectiveDateTime 
OFFSET 0 LIMIT 15   // mandatory pagination

例如,如果some_tpnb在请求参数中不为空,而其他可选过滤器为空

WHERE pci.effectiveDateTime BETWEEN "some_from_time" AND "some_to_time"   // compulsory filter 
AND 'some_tpnb' IN pci.productDSL.parameters.tpnb   // if some_tpnb is not null in request param and other optional filters are null
ORDER BY pci.effectiveDateTime DESC  //mandatory ordering by pci.effectiveDateTime 
OFFSET 0 LIMIT 15   // mandatory pagination

例如:如果some_locationClusterId不为null且其他可选过滤器为null

WHERE pci.effectiveDateTime BETWEEN "some_from_time" AND "some_to_time"   // compulsory filter 
AND 'some_locationClusterId' IN pci.locationDSL.parameters.locationClusterId   
ORDER BY pci.effectiveDateTime DESC  //mandatory ordering by pci.effectiveDateTime 
OFFSET 0 LIMIT 15   // mandatory pagination

例如:如果some_pci_state和some_cs_status不为空,并且其他可选过滤器为空

WHERE pci.effectiveDateTime BETWEEN "some_from_time" AND "some_to_time"   // compulsory filter 
AND  pci.state = "some_pci_state"   
AND cs.status = "some_cs_status"   
ORDER BY pci.effectiveDateTime DESC  //mandatory ordering by pci.effectiveDateTime DESCending order
OFFSET 0 LIMIT 15   // mandatory pagination

例如:当所有可选过滤器都存在时

WHERE pci.effectiveDateTime BETWEEN "some_from_time" AND "some_to_time"   
AND 'some_tpnb' IN pci.productDSL.parameters.tpnb   
AND 'some_locationClusterId' IN pci.locationDSL.parameters.locationClusterId   
AND  pci.state = "some_pci_state"  
AND cs.status = "some_cs_status"   
ORDER BY pci.effectiveDateTime DESC  //mandatory ordering by pci.effectiveDateTime  
OFFSET 0 LIMIT 15   // mandatory pagination

1 个答案:

答案 0 :(得分:1)

尝试一下,看看是否有帮助

SELECT  META(pci).id AS _ID,META(pci).cas AS _CAS, pci,cs
FROM prices pci
JOIN prices cs ON KEYS pci.latestCommandStatusId
WHERE pci._class = "PCI"
      AND cs._class = "CS"
      AND pci.effectiveDateTime BETWEEN "some_from_time" AND "some_to_time"
      AND 'some_tpnb' IN pci.productDSL.parameters.tpnb
      AND 'some_locationClusterId' IN pci.locationDSL.parameters.locationClusterId
      AND  pci.state = "some_pci_state"
      AND  cs.status = "some_cs_status"
ORDER BY pci.effectiveDateTime DESC
OFFSET 0 LIMIT 15

CREATE INDEX ix1 ON prices(effectiveDateTime DESC,state) WHERE _class = "PCI";