web-dev-qa-db-ja.com

Cosmos DBのクエリ-配列には項目が含まれます)配列から

このためのWordがあるかどうかはわかりませんが、あると思いますが、現時点では、「配列に配列の項目が含まれている」よりも説明することができませんでした。

奇妙に聞こえるかもしれませんが、実際はそうではありません(私はそう思います)。AzureCosmosDBでこれを行う方法を理解するのに苦労しています。

いきます私はこのような文書を持っています(簡略化):

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

}

では、このようなドキュメントをクエリしてすべてを検索します。ZipCodes.Codeは、郵便番号のリストにあります。 (「6500」、「2700」)。

私はここでパズルです...

ARRAY_CONTAINS メソッドが見つかりました。郵便番号が1つしか入らない場合は機能します。問題はリストが付いてくることです。

誰かが助けてくれるといいのですが、事前に感謝します。

16
Mads Laumann

私の経験によれば、ARRAY_CONTAINS (arr_expr, expr [, bool_expr])メソッドのexprはリスト引数をサポートしていません。

状況に応じて、Cosmos DBで [〜#〜] udf [〜#〜] を使用することをお勧めします。

説明として3つのサンプルドキュメントを作成しました。

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

以下のUDFコードのスニペットを参照してください。

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;
}

Zip配列(cからc.Zipを選択)を選択し、結果をループして、上記のUDFをZip[i]引数。

お役に立てば幸いです。


要約すると:

リスト条件に含まれているエントリをクエリするには、 Cosmos DB SQL API のIN演算子を使用します。

お気に入り

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

または

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

UDFを使用する方が簡単なオプションのように見えるという事実は別として、クエリのパフォーマンスが低下するため、クエリのフィルターでUDFを使用しません。私の作業環境でも同じ問題に直面しましたが、UDFを使用してクエリを支援するように設計されていますが、実際にはほとんどの場合、単一の値を使用してクエリを実行しており、UDFを使用すると実際にクエリが実行されますインデックスを使用しません。そのため、配列内の複数の値を検証する必要がある場合、検証する必要のある値の量に応じて、常にARRAY_CONTAINS(c、1)またはARRAY_CONTAINS(c、2)または...のようなものを書くことができます。

見た目はそれほどエレガントではありませんが、インデックスを使用し、クエリで最高のパフォーマンスを発揮します。

1
Hugo Barona

次のようなことができます:ZipCodesの各アイテムについて、Zipを取得し、チェックしているコードの配列と比較します。これは、私見ですが、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}]
}

ARRAY_CONTAINSの最後のパラメーターは、部分一致を受け入れるように関数に指示します。

0