2015-11-21 5 views
10

ich einen Tisch und GSI in Dynamos zu schaffen, um diese Parameter verwenden, gemäß der Dokumentation:Abfragen eines globalen Sekundärindex in DynamoDB Lokale

configId ist der Primärschlüssel der Tabelle, und ich bin mit dem publisherID als .

{ TableName: 'Configs', 
    IndexName: 'publisher_index', 
    KeyConditionExpression: 'publisherId = :pub_id', 
    ExpressionAttributeValues: { ':pub_id': { S: '700' } } } 

aber i: der Primärschlüssel für die GSI

var params = { 
    TableName: 'Configs', 
    KeySchema: [ 
     { 
      AttributeName: 'configId', 
      KeyType: 'HASH', 
     } 
    ], 
    AttributeDefinitions: [ 
     { 
      AttributeName: 'configId', 
      AttributeType: 'S', 
     }, 
     { 
      AttributeName: 'publisherId', 
      AttributeType: 'S', 
     } 
    ], 
    GlobalSecondaryIndexes: [ 
     { 
      IndexName: 'publisher_index', 
      KeySchema: [ 
       { 
        AttributeName: 'publisherId', 
        KeyType: 'HASH', 
       } 
      ] 
     } 
    ] 
}; 

ich Abfrage dieser Tabelle mit dieser (ich habe einige unnötige Konfigurationsparameter der Kürze entfernt) Behalten Sie den Fehler: "ValidationException: Ein oder mehrere Parameterwerte waren ungültig: Bedingung Parameter Typ stimmt nicht mit Schematyp überein"

In den Dokumenten legt es fest, dass der primäre KeyType entweder HASH oder RANGE sein kann, und dass Sie festlegen der attributeType im Feld attributeDefinitions. Ich sende die publisherId als String, nicht sicher, was ich hier vermisse.

Ist das Problem in der Art, wie ich die Tabelle erstellen oder die Art, wie ich abfrage? Dank

+0

Ich würde einen Aufruf describeTable auf den 'Configs' machen, um zu überprüfen, dass der Sekundärindex wie erwartet erstellt wurde. –

Antwort

33

Versuchen Sie, diese

{ 
TableName: 'Configs', 
IndexName: 'publisher_index', 
KeyConditionExpression: 'publisherId = :pub_id', 
ExpressionAttributeValues: { ':pub_id': { S: '700' } } 
} 

in diesem

{ 
TableName: 'Configs', 
IndexName: 'publisher_index', 
KeyConditionExpression: 'publisherId = :pub_id', 
ExpressionAttributeValues: { ':pub_id': '700'} 
} 

Von { ':pub_id': { S: '700' } }-{ ':pub_id': '700'} zu ändern.

Ich hatte das gleiche Problem und ich verbrachte 2 Tage dafür. Die offizielle Dokumentation irreführend.

+0

Sorry, ich habe das versucht, aber es funktioniert nicht für mich. Wenn ich etwas mit dem Datentyp nicht zur Verfügung stelle, wie in: {': pub_id': {S: '700'}}, erhalte ich einen Validierungsfehler. Sind Sie sicher, dass Sie nicht über ExpressionAttributesNames, sondern über ExpressionAttributesValues ​​sprechen? –

+0

Das richtige Schlüsselwort ist 'ExpressionAttributeValues' und nicht AttributeS. Sind Sie sicher, dass Ihre ValidationException nicht auf diesen kleinen Fehler zurückzuführen ist? In meinem Fall habe ich den Parameter "ExpressionAttributeNames" nicht verwendet und das hat funktioniert. – gior91

+0

@ gior91 Cool! Das hat mir wirklich geholfen. Vielen Dank! – ckuijjer

0

Sie Ihre Suchanfrage JSON mit diesem ersetzen:

{ 
    TableName: 'Configs', 
    IndexName: 'publisher_index', 
    KeyConditionExpression: '#publisherId = :pub_id', 
    ExpressionAttributeNames: { '#publisherId': 'publisherId' }, 
    ExpressionAttributeValues: { ':pub_id': { 'S': '700' } } 
} 
2

Stellt sich heraus, es hängt davon ab, ob Sie AWS.DynamoDB oder AWS.DynamoDB.DocumentClient verwenden.

Überprüfen Sie den Unterschied in der Dokumentation: AWS.DynamoDB.query vs. AWS.DynamoDB.DocumentClient.query

Im DocumentClient der doc eindeutig fest:

The document client simplifies working with items in Amazon DynamoDB by abstracting away the notion of attribute values. This abstraction annotates native JavaScript types supplied as input parameters, as well as converts annotated response data to native JavaScript types.

...

Supply the same parameters as AWS.DynamoDB.query() with AttributeValues substituted by native JavaScript types.

Vielleicht Sie, wo auch auf die DynamoDB API Reference beziehen, die in der Tat keine Annahmen macht über das verwendete SDK, verwendet jedoch reine HTTP-Anfragen in den Beispielen.

Mit der AWS.DynamoDB.DocumentClient würden Sie einfach eine Schlüssel-Wert-Map für ExpressionAttributeValues wie von @ gior91 vorgeschlagen bereitstellen.

3

Wie oben erwähnt, müssen Sie den DynamoDB Document Client verwenden, wenn Sie den Typ Casting abziehen möchten.

var docClient = new AWS.DynamoDB.DocumentClient(); 

... dann können Sie einfach die oben aufgeführte Objektnotation verwenden, um die API aufzurufen.

{ ':pub_id': '700'} 

Lief in dieser Frage mich, ich wurde mit DynamoDB() an einigen Stellen und der docClient in andere, könnte es für eine Weile nicht herausfinden, aber das wird es lösen.