我的Couchbase群集中有json文档,看起来像这样
{
"giata_properties": {
"propertyCodes": {
"provider": [
{
"code": [
{
"value": [
{
"name": "Country Code",
"value": "EG"
},
{
"name": "City Code",
"value": "HRG"
},
{
"name": "Hotel Code",
"value": "91U"
}
]
}
],
"providerCode": "gta",
"providerType": "gds"
},
{
"code": [
{
"value": [
{
"value": "071801"
}
]
},
{
"value": [
{
"value": "766344"
}
]
}
],
"providerCode": "restel",
"providerType": "gds"
},
{
"code": [
{
"value": [
{
"value": "HRG03Z"
}
]
},
{
"value": [
{
"value": "HRG04Z"
}
]
}
],
"providerCode": "5VF",
"providerType": "tourOperator"
}
]
}
}
}
我正在尝试创建一个基于giata_properties.propertyCodes.provider.code.value.value
和特定providerType
的值来获取单个文档的查询。
例如,我的输入是071801
和restel
,我想要一个查询来获取上面粘贴的文档(因为它包含这些值)。
我对N1QL很新,所以到目前为止我尝试的是(没有providerType输入)
SELECT * FROM giata_properties AS gp
WHERE ANY `field` IN `gp.propertyCodes.provider.code.value` SATISFIES `field.value` = '071801' END;
这会返回一个空结果集。我可能错误地做了所有这些。
EDIT1:
根据杰拉德斯的回答,我能够通过2个不同的查询实现我的目标
1st(更一般)~2m50.9903732s
SELECT * FROM giata_properties AS gp WHERE ANY v WITHIN gp SATISFIES v.`value` = '071801' END;
第二名(更具体)~2m31.3660388s
SELECT * FROM giata_properties AS gp WHERE ANY v WITHIN gp.propertyCodes.provider[*].code SATISFIES v.`value` = '071801' END;
Bucket有大约550K文件。目前没有索引,但主要是。
问题第2部分
当我执行上述任一查询时,我会很快将结果流式传输到我的shell,然后我花费剩余的查询时间等待引擎完成对所有文档的迭代。我相信我将来只会得到未来查询的1个结果,所以我认为我可以使用LIMIT 1,所以引擎停止搜索第一个结果,我尝试了类似
SELECT * FROM giata_properties AS gp WHERE ANY v WITHIN gp SATISFIES v.`value` = '071801' END LIMIT 1;
但这没有任何区别,我将一个文档写入我的shell,然后一直等到查询完成。如何正确配置?
EDIT2:
我已升级到最新的企业4.5.1-2844
,我只在giata_properties
存储桶上创建了主索引,当我执行查询以及LIMIT 1关键字时,它仍然需要相同的时间,它不会停止更快。
我也尝试过创建你建议的数组索引,但查询没有使用索引,并且一直坚持使用#primary
索引(即使我使用USE INDEX子句)。
我尝试从你建议的索引中删除SELF,并且花了很长时间来构建,现在查询可以使用这个新索引,但我老实说不确定我在这里做什么。
所以3个问题:
1)为什么使用主索引的LIMIT 1不会使查询在第一个结果处停止?
2)您建议使用和没有SELF的索引有什么区别?我试图查找SELF
关键字文档但我找不到任何内容。
这是两个索引在Web ui中的显示方式
索引1(您的原始建议) - 无效
CREATE INDEX `gp_idx1` ON `giata_properties`((distinct (array (`v`.`value`) for `v` within (array_star((((self.`giata_properties`).`propertyCodes`).`provider`)).`code`) end)))
索引2(不含SELF
)
CREATE INDEX `gp_idx2` ON `giata_properties`((distinct (array (`v`.`value`) for `v` within (array_star(((self.`propertyCodes`).`provider`)).`code`) end)))
3)对特定giata_properties.propertyCodes.provider.code.value.value
和特定providerCode
的查询是什么?我设法分开做了两件事,但我没有成功合并它们。
感谢您的帮助,亲爱的
答案 0 :(得分:2)
以下是没有providerType
的查询。
EXPLAIN SELECT *
FROM giata_properties AS gp
WHERE ANY v WITHIN gp.giata_properties.propertyCodes.provider[*].code SATISFIES v.`value` = '071801' END;
您也可以在Couchbase 4.5.0及更高版本中对此进行索引。
CREATE INDEX idx1 ON giata_properties( DISTINCT ARRAY v.`value` FOR v WITHIN SELF.giata_properties.propertyCodes.provider[*].code END );
编辑以回答问题修改
性能已在4.5.x中得到解决。您应该在Couchbase 4.5.1上尝试以下操作并在此处发布执行时间。