Cloudant/Mango селектор для глубоко вложенных 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, который может успешно выбрать "i_look_for"
имея значение "this_tag"
? Это внутри массива (я знаю его положение в массиве). Я также заинтересован в фильтрации результатов, поэтому я получаю только "tag_properties"
в результате.
Я перепробовал много вещей, в том числе $elemMatch, но все в основном возвращают "неверный json".
Это даже вариант использования для Mango или я должен придерживаться взглядов?
2 ответа
С помощью операторов селектора Cloudant Query (Mango) вам все равно необходимо определить соответствующий индекс перед выполнением запросов. Имея это в виду, вот ваш ответ:
индекс CQ типа json
{
"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"
]
}
Решение выше предполагает, что вы всегда знаете / можете гарантировать, что поля, которые вы хотите, находятся в пределах 0-го элемента is_down_here
массив.
Есть другой способ ответить на этот вопрос с другим типом индекса CQ. Эта статья объясняет различия и имеет полезные примеры, которые показывают запрашивающие массивы. Теперь, когда вы узнали немного больше о различных типах индексов, вот как вы ответите на свой вопрос с помощью индекса CQ типа Lucene search / "text":
текстовый индекс 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-типа меньше и менее гибки (могут индексировать только определенные элементы); Тип текста больше, но более гибкий (может индексировать все элементы массива). И из этого примера вы также можете увидеть, что прогнозируемые значения также идут с некоторыми компромиссами (проекция определенных значений против всего массива).
Больше примеров в этих темах:
Если я правильно понимаю ваш вопрос, есть два поддерживаемых способа сделать это в соответствии с документами:
{
"what_i_want": {
"i_look_for": "this_tag"
}
}
должен быть эквивалентен сокращенной форме:
{
"what_i_want.i_look_for": "this_tag"
}