yuyu kungkung
yuyu kungkung

Reputation: 137

how to query or search with one Primary Key and One Attribute in DynamoDb

i have database like this :

Symbol are primaryKey and priceId is SortKey and others are attributes priceId as sortkey always unique

enter image description here

i have information only symbol and savetime

for example is

String Symbols = "EURUSD"; String time = "2020-06-10 09:12:07";

i have try use scan but my code stack

Table table = dynamoDB.getTable(tableName);
        System.out.println("runFirstTime For Search Data");
        String Symbols = "EURUSD";
        String time = "2020-06-10 09:12:07";
        try{
            Map<String, AttributeValue> expressionAttributeValues = new HashMap<String, AttributeValue>(); 
            expressionAttributeValues.put(":savetime", new AttributeValue().withS(time));
            expressionAttributeValues.put(":symbol", new AttributeValue().withS(Symbols));
            ScanRequest scanRequest = new ScanRequest().withTableName(tableName).withFilterExpression("savetime = :savetime AND symbol = :symbol")
                    .withProjectionExpression("symbol, priceId, savetime, Price").withExpressionAttributeValues(expressionAttributeValues);
            ScanResult result = client.scan(scanRequest);
            for (Map<String, AttributeValue> item : result.getItems()) {
                System.out.println(item);
            }
        }catch (Exception e) {
             System.err.println("Cannot retrieve items.");
             System.err.println(e.getMessage());
          }
    }

my code stack in log4j:WARN No appenders could be found for logger

(com.amazonaws.AmazonWebServiceClient).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
runFirstTime For Search Data

i also have try use query and change my database structure like this enter image description here

and i have try to code use this

Table table = dynamoDB.getTable(tableName);
        System.out.println("runFirstTime For Search Data");
        String Symbols = "EURUSD";
        String time = "2020-06-10 11:43:31";
        String Prefix = "Onezero";
          ItemCollection<QueryOutcome> items = null;
            Iterator<Item> iterator = null;
            Item item = null;
        try{
            QuerySpec spec = new QuerySpec().withProjectionExpression("symbol, priceId, Price, savetime")
                    .withKeyConditionExpression("symbol = :v_symbol and begin_with(priceId, :begin)")
                    .withFilterExpression("savetime = :v_savetime")
                    .withValueMap(new ValueMap()
                            .withString(":v_symbol", Symbols)
                            .withString("begin", Prefix)
                            .withString(":v_savetime", time));
            items = table.query(spec);
            iterator = items.iterator();
            while (iterator.hasNext()) {
                item = iterator.next();
                System.out.println(item.getString("symbol") + ": " + item.getString("savetime") + ": "+ item.getString("Price"));
            }

        }catch (Exception e) {
             System.err.println("Cannot retrieve items.");
             System.err.println(e.getMessage());
          }
    }

but i still got an error like this one

ExpressionAttributeValues contains invalid key: Syntax error; key: "begin" (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: 5TTRE1Q7FBT5TLNL0MTTPV05K7VV4KQNSO5AEMVJF66Q9ASUAAJG; Proxy: null)

why like that ? maybe error in scan. so what is best to use to search from 1 key and 1 attribute use dynamoDb ? any example for that ?

i have try use getitem or scan but still have problem

Upvotes: 0

Views: 1560

Answers (2)

yuyu kungkung
yuyu kungkung

Reputation: 137

this problem done when i use this code

Table table = dynamoDB.getTable(tableName);
        System.out.println("runFirstTime For Search Data");
        String Symbols = "EURUSD";
        String time = "2020-06-11 03:20:52";
        String Prefix = "Onezero";
          ItemCollection<QueryOutcome> items = null;
            Iterator<Item> iterator = null;
            Item item = null;
        try{
            QuerySpec spec = new QuerySpec().withProjectionExpression("symbol, priceId, Price, savetime")
                    .withKeyConditionExpression("symbol = :v_symbol and begins_with(priceId, :begin)")
                    .withFilterExpression("begins_with(savetime, :v_savetime)")
                    .withValueMap(new ValueMap()
                            .withString(":v_symbol", Symbols)
                            .withString(":begin", Prefix)
                            .withString(":v_savetime", time));
            items = table.query(spec);
            iterator = items.iterator();
            while (iterator.hasNext()) {
                item = iterator.next();
                System.out.println(item.getString("symbol") + ": " + item.getString("savetime") + ": "+ item.getString("Price"));
            }

        }catch (Exception e) {
             System.err.println("Cannot retrieve items.");
             System.err.println(e.getMessage());
          }

thanks for everyone help here.

Upvotes: 1

Iris Hunkeler
Iris Hunkeler

Reputation: 208

You seem to be mixing multiple issues here...

For your DynamoDB query: I think, you should probably use a KeyConditionExpression to filter for symbol (because that is your partition key) combined with a FilterExpression for savetime. The docs provide some examples: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryingJavaDocumentAPI.html

Be aware: DynamoDB will load all entries which match the KeyConditionExpression (i.e. this is the load you will pay for) and apply the FilterExpression afterwards. But that is the expected behaviour, you can restrict the query only by your keys.

For your log4j warning, please check the answers to the questions here:

Upvotes: 0

Related Questions