2016-04-18 3 views
0

Ich möchte über filterExpression für AWSDynamoDBScanExpression fragen. Problem:AWS Batch-Anfrage für mehrere Elemente gefiltert durch Array von Werten

Ich möchte db für alle Objekt in einer Tabelle durchsuchen, wo ein Parameter (nennen wir es uniqueId) ist eine der Wert in einem Array gespeichert (Array der erforderlichen UniqueIDs).

Für ein Objekt - es ist einfach zu tun mit

AWSDynamoDBScanExpression *scanExpression = [[AWSDynamoDBScanExpression alloc] init]; 
scanExpression.expressionAttributeNames = @{ 
              @"#P": [NSString stringWithFormat:@"%@", property] 
              }; 
scanExpression.filterExpression [email protected]"#P = :val"; 
scanExpression.expressionAttributeValues = @{ 
              @":val" : @"some uniqueID" 
              }; 

so in derselben Logik mag ich db für Multi Objekte

AWSDynamoDBScanExpression *scanExpression = [[AWSDynamoDBScanExpression alloc] init]; 
scanExpression.expressionAttributeNames = @{ 
              @"#P": [NSString stringWithFormat:@"%@", property] 
              }; 
scanExpression.filterExpression = <WHAT SHOULD BE HERE, WHAT EXPRESSION>; 
scanExpression.expressionAttributeValues = @{ 
              @":val" : [@"some unique id 1", 
              @"some unique id 2", 
              @"some unique id 3"] 
              }; 

Ist eine Möglichkeit, scannen scanExpression.filterExpression zu ändern, um dies zu achive ?

EDIT 1

Nein, ich bin nicht sicher, dass scan die beste Lösung ist. Eigentlich query ist die beste Variante denke.

Die Struktur der Tabelle

enter image description here

#P = :val1 OR #P = :val2 make sense

EDIT2

Dies ist einige Update:

AWSDynamoDBQueryExpression *query = [[AWSDynamoDBQueryExpression alloc] init]; 
NSMutableDictionary *dictionaryAttributes = [[NSMutableDictionary alloc] init]; 
NSString *expression = @""; 
for (int i = 0; i < filteredHashValues.count; i++) { 
    NSString *variableName = [NSString stringWithFormat:@":val%i", i]; 
    [dictionaryAttributes setValue:filteredHashValues[i] forKey:variableName]; 
    expression = [expression stringByAppendingString:expression.length ? [NSString stringWithFormat:@"OR #P = %@ " , variableName] : [NSString stringWithFormat:@"#P = %@ " , variableName]]; 
} 

query.indexName = @"uniqueId-index"; 
query.expressionAttributeNames = @{ 
            @"#P": [NSString stringWithFormat:@"%@", @"uniqueId"] 
            }; 
query.filterExpression = expression; 
query.expressionAttributeValues = dictionaryAttributes; 

AWSDynamoDBObjectMapper *dynamoDBObjectMapper = [AWSDynamoDBObjectMapper defaultDynamoDBObjectMapper]; 
[[dynamoDBObjectMapper query:className expression:query] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { 

    if (task.result) { 
     AWSDynamoDBPaginatedOutput *output = task.result; 
    } 
    return nil; 
}]; 

Aber führen

Printing description of expression: #P = :val0 OR #P = :val1 OR #P = :val2 OR #P = :val3

Printing description of dictionaryAttributes: { ":val0" = "8A93A3EA-9FB9-4396-BBF6-D0BD3CBE6BE5"; ":val1" = "08533EBA-D3E5-406C-8CDE-03EECCCA801B"; ":val2" = "954AE402-336E-423D-BF03-7E8AED1446FE"; ":val3" = "F683BDF8-0507-4218-9927-9F14D470E593"; }

Printing description of task->_error: Error `Domain=com.amazonaws.AWSDynamoDBErrorDomain Code=0 "(null)" UserInfo={__type=com.amazon.coral.validate#ValidationException, message=ExpressionAttributeValues contains invalid value: Supplied AttributeValue is empty, must contain exactly one of the supported datatypes for key :awsddbomhashvalueplaceholder}

sieht aus wie ExpressionAttributeValues ist leer - mache ich alles richtig?

Antwort

1

Sind Sie sicher, dass Sie einen Scanausdruck verwenden möchten? das verbraucht wirklich viel Lesekapazität und kann Ihre Dynamob Performance ruinieren: ein Scan liest Ihnen die gesamte Tabelle vor und nur DANN wendet den Filter an und gibt die Werte zurück.

Wenn Sie uns Ihre tatsächliche dynamodb-Tabellenstruktur zur Verfügung stellen, könnten wir vielleicht eine andere Lösung besprechen. Zum Beispiel könnte eine Lösung darin bestehen, einen globalen sekundären Index (falls ein konsistentes Lesen für Sie in Ordnung ist) oder einen lokalen sekundären Index (mit seinen Einschränkungen) mit einem Bereichsschlüssel auf Ihrem zu filternden Wert zu erstellen. Dies würde es Ihnen ermöglichen, Abfragen zu verwenden, die viel besser sind und Empfehlungen für Best Practices geben.

Das heißt, können Sie nur Bedingungen zu Ihrem Filter hinzuzufügen mit Operatoren AND und OR, was zu etw ähnlich wie "#P =: val1 OR #P =: val2"

Hoffnung, die

+0

hilft Bitte sehen Sie edit1 – gbk

+0

Haben Sie ein Feld in dieser Tabelle, das sich oft genug ändert (dh ist nicht unbedingt einzigartig, aber hat viele verschiedene Werte), anders als uniqueId? Ich denke zum Beispiel an GroupId oder ParentKey. Dies ist erforderlich, um einen Index zu erstellen, während die bereitgestellte Kapazität optimiert bleibt. Ein Index würde Ihnen erlauben, ein bestimmtes Feld (uniqueId in Ihrem Fall) schön abzufragen, während Sie Ihre Kapazität – Tom

+0

nicht ruinieren, sehen Sie bitte Edit 2 – gbk