N1QL 嵌套 json,查询数组内对象内的字段
N1QL nested json, query on field inside object inside array
我的 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;
这 returns 我是一个空结果集。我可能做错了这一切。
edit1:
根据 geraldss 的回答,我能够通过 2 个不同的查询实现我的目标
第 1(更一般)~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 非常 quickly,然后我用剩下的查询时间等待引擎完成遍历所有文档。我确定我只会从未来的查询中得到 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 关键字执行查询时,它仍然采用相同的方式时间,它不会停止 quicker.
我也试过创建你建议的数组索引,但查询没有使用索引,它一直坚持使用 #primary
索引(即使我使用 USE INDEX 子句)。
我尝试从您建议的索引中删除 SELF,但 build 花费了更长的时间,现在查询可以使用这个新索引,但老实说我不确定我在做什么在这里做。
所以 3 个问题:
1) 为什么使用主索引的 LIMIT 1 不会使查询在第一个结果处停止?
2) 您建议的带 SELF 和不带 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
的查询是什么?我设法分别做了这两个,但我没有成功合并它们。
谢谢你的帮助亲爱的
这是一个没有 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 上尝试以下操作,post 这里的执行时间。
- 4.5.1 测试
- 创建索引。
- 使用限制。 4.5.1中limit下推到index
我的 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;
这 returns 我是一个空结果集。我可能做错了这一切。
edit1:
根据 geraldss 的回答,我能够通过 2 个不同的查询实现我的目标
第 1(更一般)~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 非常 quickly,然后我用剩下的查询时间等待引擎完成遍历所有文档。我确定我只会从未来的查询中得到 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 关键字执行查询时,它仍然采用相同的方式时间,它不会停止 quicker.
我也试过创建你建议的数组索引,但查询没有使用索引,它一直坚持使用 #primary
索引(即使我使用 USE INDEX 子句)。
我尝试从您建议的索引中删除 SELF,但 build 花费了更长的时间,现在查询可以使用这个新索引,但老实说我不确定我在做什么在这里做。
所以 3 个问题:
1) 为什么使用主索引的 LIMIT 1 不会使查询在第一个结果处停止?
2) 您建议的带 SELF 和不带 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
的查询是什么?我设法分别做了这两个,但我没有成功合并它们。
谢谢你的帮助亲爱的
这是一个没有 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 上尝试以下操作,post 这里的执行时间。
- 4.5.1 测试
- 创建索引。
- 使用限制。 4.5.1中limit下推到index