Cloudant/Mango 深度嵌套 JSON 的选择器
Cloudant/Mango selector for deeply nested JSONs
假设我的一些文档具有以下结构:
{
"something":{
"a":"b"
},
"some_other_thing":{
"c":"d"
},
"what_i_want":{
"is_down_here":[
{
"some":{
"not_needed":"object"
},
"another":{
"also_not_needed":"object"
},
"i_look_for":"this_tag",
"tag_properties":{
"this":"that"
}
},
{
"but_not":{
"down":"here"
}
}
]
}
}
是否有 Mango JSON select 或可以在 "i_look_for"
上成功 select 且值为 "this_tag"
的?它在一个数组中(我知道它在数组中的位置)。我也对过滤结果感兴趣,所以我只得到结果中的 "tag_properties"
。
我尝试了很多东西,包括 $elemMatch,但大部分都是 return "invalid json"。
这甚至是 Mango 的用例还是我应该坚持使用视图?
如果我没有正确理解你的问题,根据 docs:
有两种支持的方法
{
"what_i_want": {
"i_look_for": "this_tag"
}
}
应该等同于缩写形式:
{
"what_i_want.i_look_for": "this_tag"
}
使用Cloudant Query (Mango) 选择器语句,您仍然需要在查询前定义一个合适的索引。考虑到这一点,这是您的答案:
json-型CQ指数
{
"index": {
"fields": [
"what_i_want.is_down_here.0"
]
},
"type": "json"
}
针对json类型索引的选择器
{
"selector": {
"what_i_want.is_down_here.0": {
"i_look_for": "this_tag"
},
"what_i_want.is_down_here.0.tag_properties": {
"$exists": true
}
},
"fields": [
"_id",
"what_i_want.is_down_here.0.tag_properties"
]
}
上面的解决方案假定您总是know/can保证您想要的字段在is_down_here
数组的第0个元素内。
有另一种方法可以使用不同的 CQ 索引类型来回答这个问题。 This article explains the differences,并提供了显示查询数组的有用示例。现在您对不同的索引类型有了更多的了解,下面是您如何使用 Lucene 搜索/"text" 类型的 CQ 索引来回答您的问题:
文本型CQ指数
{
"index": {
"fields": [
{"name": "what_i_want.is_down_here.[]", "type": "string"}
]
},
"type": "text"
}
针对文本类型索引的选择器
{
"selector": {
"what_i_want.is_down_here": {
"$and": [
{"$elemMatch": {"i_look_for": "this_tag"}},
{"$elemMatch": {"tag_properties": {"$exists": true}}}
]
}
},
"fields": [
"_id",
"what_i_want.is_down_here"
]
}
阅读这篇文章,您将了解到每种方法都有其优缺点: json 类型的索引更小且更不灵活(只能索引特定元素);文本类型更大但更灵活(可以索引所有数组元素)。从这个例子中,您还可以看到投影值也有一些权衡(投影特定值与整个数组)。
这些线程中的更多示例:
假设我的一些文档具有以下结构:
{
"something":{
"a":"b"
},
"some_other_thing":{
"c":"d"
},
"what_i_want":{
"is_down_here":[
{
"some":{
"not_needed":"object"
},
"another":{
"also_not_needed":"object"
},
"i_look_for":"this_tag",
"tag_properties":{
"this":"that"
}
},
{
"but_not":{
"down":"here"
}
}
]
}
}
是否有 Mango JSON select 或可以在 "i_look_for"
上成功 select 且值为 "this_tag"
的?它在一个数组中(我知道它在数组中的位置)。我也对过滤结果感兴趣,所以我只得到结果中的 "tag_properties"
。
我尝试了很多东西,包括 $elemMatch,但大部分都是 return "invalid json"。
这甚至是 Mango 的用例还是我应该坚持使用视图?
如果我没有正确理解你的问题,根据 docs:
有两种支持的方法{
"what_i_want": {
"i_look_for": "this_tag"
}
}
应该等同于缩写形式:
{
"what_i_want.i_look_for": "this_tag"
}
使用Cloudant Query (Mango) 选择器语句,您仍然需要在查询前定义一个合适的索引。考虑到这一点,这是您的答案:
json-型CQ指数
{
"index": {
"fields": [
"what_i_want.is_down_here.0"
]
},
"type": "json"
}
针对json类型索引的选择器
{
"selector": {
"what_i_want.is_down_here.0": {
"i_look_for": "this_tag"
},
"what_i_want.is_down_here.0.tag_properties": {
"$exists": true
}
},
"fields": [
"_id",
"what_i_want.is_down_here.0.tag_properties"
]
}
上面的解决方案假定您总是know/can保证您想要的字段在is_down_here
数组的第0个元素内。
有另一种方法可以使用不同的 CQ 索引类型来回答这个问题。 This article explains the differences,并提供了显示查询数组的有用示例。现在您对不同的索引类型有了更多的了解,下面是您如何使用 Lucene 搜索/"text" 类型的 CQ 索引来回答您的问题:
文本型CQ指数
{
"index": {
"fields": [
{"name": "what_i_want.is_down_here.[]", "type": "string"}
]
},
"type": "text"
}
针对文本类型索引的选择器
{
"selector": {
"what_i_want.is_down_here": {
"$and": [
{"$elemMatch": {"i_look_for": "this_tag"}},
{"$elemMatch": {"tag_properties": {"$exists": true}}}
]
}
},
"fields": [
"_id",
"what_i_want.is_down_here"
]
}
阅读这篇文章,您将了解到每种方法都有其优缺点: json 类型的索引更小且更不灵活(只能索引特定元素);文本类型更大但更灵活(可以索引所有数组元素)。从这个例子中,您还可以看到投影值也有一些权衡(投影特定值与整个数组)。
这些线程中的更多示例: