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"
}
Другие вопросы по тегам