2017-04-30 3 views
0

profondément imbriquées Supposons que certains de mes documents ont la structure suivante:Cloudant/sélecteur Mango pour 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" 
      } 
     } 
     ] 
    } 
} 

Y at-il un sélecteur JSON Mango qui permet de sélectionner avec succès sur "i_look_for" ayant la valeur "this_tag"? C'est à l'intérieur d'un tableau (je connais sa position dans le tableau). Je suis également intéressé par le filtrage du résultat, donc je n'ai que le "tag_properties" dans le résultat.

J'ai essayé beaucoup de choses, y compris $ elemMatch mais tout retourne principalement "invalide json".

Est-ce encore un cas d'utilisation pour Mango ou dois-je m'en tenir aux vues?

Répondre

4

Avec Cloudant Instructions de sélecteur Query (Mango), vous devez toujours définir un index approprié avant l'interrogation. Dans cet esprit, voici votre réponse:

index CQ JSON type

{ 
    "index": { 
    "fields": [ 
     "what_i_want.is_down_here.0" 
    ] 
    }, 
    "type": "json" 
} 

Sélecteur contre index de type 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" 
    ] 
} 

La solution ci-dessus suppose que vous savez toujours/peut garantir que les champs que vous voulez sont dans le 0ème élément du tableau is_down_here.

Il existe une autre façon de répondre à cette question avec un type d'index CQ différent. This article explains the differences, et a des exemples utiles qui montrent des tableaux d'interrogation. Maintenant que vous savez un peu plus sur les différents types d'index, voici comment vous répondre à votre question avec une recherche Lucene/"text" index de type CQ:

index CQ type texte

{ 
    "index": { 
    "fields": [ 
     {"name": "what_i_want.is_down_here.[]", "type": "string"} 
    ] 
    }, 
    "type": "text" 
} 

Sélecteur contre index de type texte

{ 
    "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" 
    ] 
} 

Lire l'article et vous apprendrez que chaque approche a ses compromis: les index de type JSON sont plus petits et moins souple (indice ne peut éléments spécifiques); Le type de texte est plus grand mais plus flexible (peut indexer tous les éléments du tableau). Et à partir de cet exemple, vous pouvez également voir que les valeurs projetées s'accompagnent de quelques compromis (projection de valeurs spécifiques par rapport à l'ensemble du tableau).

d'autres exemples dans ces discussions:

2

Si je comprends bien votre question, il y a deux façons de le faire pris en charge selon le docs:

{ 
    "what_i_want": { 
     "i_look_for": "this_tag" 
    } 
} 

devrait être équivalente à la forme abrégée:

{ 
    "what_i_want.i_look_for": "this_tag" 
} 
+0

retourne 0 docs: Je comprends c'est parce que 'i_look_for' est pas une propriété directe de' what_i_want', mais un membre du tableau 'is_down_here' – zlr

+2

Avez-vous essayé' what_i_want.0.i_look_for'? – Flimzy

+2

Très cool, ça marche. J'ai essayé cette notation d'index de tableau mais ai échoué, ainsi merci! La prochaine question est comment puis-je éviter les arguments positionnels, mais il y a une nouvelle réponse à ce sujet, donc je devrais être tous ensemble – zlr