2017-04-25 31 views
0

私は、DynamoDBを使い始めようとしている.NET開発者です。 私は、グローバルなセカンダリインデックスでクエリを実行しようとしばらく時間を費やしましたが、予想よりも難しくなっています。私はテーブルとインデックスを作成しました。私はアイテムを格納し、GUIDである主キーによってそれらを戻すことができます。私は動作しないクエリの2つの方法を示します。私もこれらのバリエーションをいくつか試しました。 .NET Coreを使用しています。私の項目は主キー(GUID)としてMappingIdを持っています。しかし、かなり頻繁に私はProductIdでそれらを探しますので、私はセカンダリグローバルインデックスを作成しました。.NETを使用したDynamo DBのセカンダリインデックスの照会

これは、テーブルとインデックスを作成するためのコードです:

private Table CreateTable(string tableName) 
    { 

     CreateTableRequest createRequest = null; 

     if (tableName == "ProductLevelProductPropertyMapping") 
     { 
      createRequest = new CreateTableRequest 
      { 
       TableName = "ProductLevelProductPropertyMapping", 
       AttributeDefinitions = new List<AttributeDefinition>() 
       { 
        new AttributeDefinition 
        { 
         AttributeName = "MappingId", 
         AttributeType = "S" 
        } , 
        new AttributeDefinition 
        { 
         AttributeName = "ProductId", 
         AttributeType = "N" 
        } 

       }, 
       KeySchema = new List<KeySchemaElement>() 
        { 
         new KeySchemaElement 
         { 
          AttributeName = "MappingId", 
          KeyType = "HASH" 
         } 
        }, 

       GlobalSecondaryIndexes = new List<GlobalSecondaryIndex>() 
        { 
         new GlobalSecondaryIndex() 
         { 
          IndexName = "ProductIdIdx", 

          KeySchema = new List<KeySchemaElement>() 
          { 
           new KeySchemaElement 
           { 
            AttributeName = "ProductId", 
            KeyType = "HASH" 
           } 
          } 

         } 
        }, 




      }; 


     } 



     if (tableName == "SupplierLevelProductPropertyMapping") 
     { 
      // Create Something else 
      . 
      . 

     } 


     // Build a 'CreateTableRequest' for the new table 


     // Provisioned-throughput settings are required even though 
     // the local test version of DynamoDB ignores them 
     createRequest.ProvisionedThroughput = new ProvisionedThroughput(1, 1); 
     createRequest.GlobalSecondaryIndexes[0].ProvisionedThroughput = new ProvisionedThroughput(1, 1); 
     createRequest.GlobalSecondaryIndexes[0].Projection = new Projection() { ProjectionType = ProjectionType.ALL }; 

     // Using the DynamoDB client, make a synchronous CreateTable request 

     try 
     { 
      var task = client.CreateTableAsync(createRequest); 
      task.Wait(); 

      Console.WriteLine("\n\n Created the {0} table successfully!\n Status of the new table: '{1}'", tableName, task.Result.TableDescription.TableStatus); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("\n Error: failed to create the new table; " + ex.Message); 

      return null; 
     } 


     return Table.LoadTable(client, tableName); 


    } 

私はデシベル内の項目の一握りを持っていますが、 クエリにこの方法がゼロのヒットを与える:

私が持っている
public ProductLevelProductPropertyMapping GetProductLevelItemByProductId(int productId) 
    { 

     var request = new QueryRequest 
     { 
      TableName = "ProductLevelProductPropertyMapping", 
      IndexName = "ProductIdIdx", 
      KeyConditionExpression = "ProductId = :v_Id", 
      ExpressionAttributeValues = new Dictionary<string, AttributeValue> { 
      {":v_Id", new AttributeValue { N = productId.ToString() }}} 
     }; 

     var task = client.QueryAsync(request); 

     task.Wait(); 

     var result = task.Result.Items; //Zero hits 
     . 
     . 
     //Return some item here 
    } 

Amazonsの文書にも同様の例があります。しかし、彼らが何をやろうとしているのか、それがどういうものなのかは私には分かりません。

public ProductLevelProductPropertyMapping GetProductLevelItemByProductId(int productId) 
    { 

     var myAttributes = new List<AttributeValue>(); 

     myAttributes.Add(new AttributeValue($"'N' : '{0}' " + productId.ToString())); 


     var myQF = new QueryFilter("ProductId", QueryOperator.Equal, myAttributes); 

     var conf = new QueryOperationConfig() 
     { 
      IndexName = "ProductIdIdx", 
      Filter = myQF 
     }; 


     var someSearchObject = productLevelTable.Query(conf); 


     var f = someSearchObject.Count; 

     . 
     . 
     //return some result object. 

    } 

照会の第二の方法は私にメッセージとAmazonDynamoDBExceptionできます::私もこの方法を試してみましたが、私は例外を取得http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSILowLevelDotNet.html#GSILowLevelDotNet.QueryAnIndex

つ以上のパラメータ値が無効だった:条件パラメータタイプはありませんスキーマタイプと一致しません。

誰でも私が間違っていることについて私にいくつかの入力を与えることができますか?

+0

ここでは、ProductLevelProductPropertyMappingオブジェクトの使用方法については説明しません。私はそれが重要ではないと思う。それはアイテムです。私はそれを保存し、後でそれを取得したい。 MappingIdまたはProductIdを使用できます。 – user3042674

答えて

1

2番目の、より高度な方法では、QueryFilterの最後のパラメータとしてproductIdを送信するだけです。このように:

var myQF = new QueryFilter("ProductId", QueryOperator.Equal, productId);

あなたが得たエラーメッセージは、あなたのオブジェクトタイプ(List<AttributeValue>)は、インデックスのハッシュキーの種類(番号のN)と一致しないことを意味します。この場合、任意の種類の数値、整数を送信することが期待されます。

さらに問題がある場合は、それを試して、更新された質問に戻ってください。 AWS @ PejusがAWS Forumに言うよう


あなたの答えで推論への返信で

更新...

DynamoDBのは、大文字と小文字が区別されます。

私が起こったと思われることは、ドキュメント/アイテムに「productid」フィールドを追加し、それをテーブルに格納することです(あなたが言うように)。任意の名前のフィールドは、テーブル構造に指定することなく、ドキュメントに追加できます。したがって、同時に「productid」と「ProductId」のような2つのフィールドを同時に追加することができます。

テーブルをクエリすると、テーブルの既存のプロパティではなく、テーブル定義に対してクエリが確認されます。したがって、追加されたドキュメント/アイテムには存在しないフィールド "ProductId"を検索する有効なクエリがあるため、アイテムを見つけられませんでした。したがって、クエリはテーブル定義と一致し、論理的にはアイテムを返さなかったため、以前はokでした。例外をスローしてはいけません。

良いことはとにかく解決しました。

+0

あなたの説明は理にかなっています。私も同じ結論に達しましたが、コードが動作しているのを見てから、それが沈んでいくには時間がかかりました。ところで、低レベルのクエリは、私がケーシングの問題を見つけた後にも働いています。しかし、とにかくそれを避けたいと思う。 – user3042674

0

ありがとうございましたあなたの提案コードラインはソリューションの一部でした。

var myQF = new QueryFilter("ProductId", QueryOperator.Equal, productId); 

例外なくクエリを実行しますが、ヒット件数はゼロです。しかし、ケーシングの問題もありました。テーブルとインデックスを作成するときに私は "ProductId"を使用しました。文書を保存するとき、私はこのように "productid"を書いていました:

myDoc["productid"] = item.ProductId; 

これはヒットは0になりますが、例外はありませんでした。しかし、存在しない属性を照会しようとすると、エラーが発生します。

var myQF = new QueryFilter("SoEasyToGetStarted", QueryOperator.Equal, productId); 

次に例外が発生します。だから私は少し「productid」と「ProductId」を混在させても例外はありません。ダイナモが大文字と小文字を区別しない場合、私はクエリのヒットを予想しました。とにかく、今は物事が働いています。

関連する問題