web-dev-qa-db-fra.com

Query Cosmos Db - où le tableau contient des éléments) à partir du tableau

Je ne sais pas s'il y a un mot pour cela, je suppose que oui, mais pour l'instant je ne pourrais pas l'expliquer mieux que "où le tableau contient des éléments du tableau".

Cela peut sembler étrange, mais en fait ce n'est pas le cas (je pense), et j'ai du mal à comprendre comment je peux le faire dans Azure CosmosDB.

Voici. J'ai un document comme celui-ci (simplifié):

{
"id": "2a62fcf4-988f-4ebe-aedc-fb0c664b85d8",
"Title": "Seks års fængsel for overgreb",    
"ZipCodes": [
    {
        "Code": "6500",
        "Name": "Vojens",
        "FoundViaTerm": "Vojens"
    },
    {
        "Code": "6400",
        "Name": "Sønderborg",
        "FoundViaTerm": "Sønderborg"
    },
    {
        "Code": "6700",
        "Name": "Esbjerg",
        "FoundViaTerm": "Esbjerg"
    }
],
"_rid": "k1sVAPf7SQAMAAAAAAAAAA==",
"_self": "dbs/k1sVAA==/colls/k1sVAPf7SQA=/docs/k1sVAPf7SQAMAAAAAAAAAA==/",
"_etag": "\"00001000-0000-0000-0000-5a14898e0000\"",
"_attachments": "attachments/",
"_ts": 1511295374

}

Ok, maintenant je veux interroger des documents comme celui-ci et trouver tout, où ZipCodes.Code est dans une liste de zipcodes, ex. ('6500', '2700').

Je suis un puzzle ici ...

J'ai trouvé la méthode ARRAY_CONTAINS et cela fonctionne, si je n'entre qu'avec un seul code postal - mon problème est que je viens avec une liste.

J'espère que quelqu'un pourra vous aider, merci d'avance.

16
Mads Laumann

D'après mon expérience, la méthode expr dans ARRAY_CONTAINS (arr_expr, expr [, bool_expr]) n'est pas prise en charge les arguments de liste.

Selon votre situation, je vous suggère d'utiliser UDF dans Cosmos DB.

J'ai créé 3 exemples de documents comme description.

[
  {
    "id": "1",
    "Zip": [
      {
        "code": "1111"
      },
      {
        "code": "2222"
      }
    ]
  },
  {
    "id": "2",
    "Zip": [
      {
        "code": "2222"
      },
      {
        "code": "3333"
      }
    ]
  },
  {
    "id": "3",
    "Zip": [
      {
        "code": "4444"
      },
      {
        "code": "1111"
      },
      {
        "code": "2222"
      }
    ]
  }
]

Veuillez vous référer à l'extrait de code UDF ci-dessous:

function test(zipcode){
    var arrayList = ["1111","2222"]
    var ret = false ;
    for(var i=0 ;i <zipcode.length;i++){
        if(arrayList.indexOf(zipcode[i].code)){
            ret= true;
        }else{
            ret = false;
            break;
        }
    }
    return ret;
}

Vous pouvez sélectionner un tableau Zip (sélectionnez c.Zip dans c), puis bouclez les résultats et appelez l'UDF ci-dessus dans votre code avec le Zip[i] arguments.

J'espère que cela vous aide.


Juste pour le résumé:

Utilisez l'opérateur IN de API SQL Cosmos DB pour interroger l'entrée qui est incluse dans la condition de liste.

Comme

SELECT * FROM c WHERE c.ZipCodes[0].Code IN ("6500", "6700")

Ou

SELECT * FROM c JOIN zc IN c.ZipCodes WHERE zc.Code IN ("2720", "2610")
10
Jay Gong

Mis à part le fait que l'utilisation d'UDF semble être l'option la plus simple, je n'utiliserais pas d'UDF dans le filtre de votre requête, car cela compromet les performances de votre requête. J'ai rencontré le même problème dans mon environnement de travail, où les choses sont conçues pour utiliser les FDU pour aider dans les requêtes, mais la réalité est que la plupart du temps, nous effectuons des requêtes en utilisant des valeurs uniques, et l'utilisation de FDU se traduira en fait sur la requête n'utilise pas l'index. Donc, dans ce cas, si vous devez valider plusieurs valeurs dans le tableau, selon le volume de valeurs que vous devez valider, vous pouvez toujours écrire quelque chose comme ARRAY_CONTAINS (c, 1) ou ARRAY_CONTAINS (c, 2) ou ....

Il n'a pas l'air d'une solution aussi élégante, mais garantira qu'il utilisera l'index et fera les meilleures performances dans votre requête.

1
Hugo Barona

Vous pouvez faire quelque chose comme ceci: Pour chaque élément dans ZipCodes, vous obtenez un Zip et comparez avec le tableau de codes que vous vérifiez. Cela, à mon humble avis, est beaucoup mieux que d'utiliser UDF.

{
  query: '
         SELECT DISTINCT value r
         FROM root r
         JOIN Zip IN r.zipCodes
         WHERE ARRAY_CONTAINS(@zipIds, Zip, true)
         ',
  parameters: [{name: "@zipIds", value: zipIds}]
}

Le dernier paramètre de ARRAY_CONTAINS indique à la fonction d'accepter des correspondances partielles.

0
Sandokan El Cojo