IN query with DynamoDB table is not working - java

ScanRequest with IN on a list field is not matching with the entries in DynamoDB.
Code:
Map<String, AttributeValue> userAttributeValues = new HashMap<>();
userAttributeValues.put(":topic1", new AttributeValue().withS("5"));
userAttributeValues.put(":topic2", new AttributeValue().withS("11"));
ScanRequest scanRequest = new ScanRequest()
.withTableName("user")
.withFilterExpression("subscribedTopics IN (:topic1, :topic2)")
.withProjectionExpression("userId")
.withExpressionAttributeValues(userAttributeValues);
ScanResult result = dynamoDBClient.scan(scanRequest);
System.out.println("Number of results: " + result.getCount());
for (Map<String, AttributeValue> userItemsMap : result.getItems()) {
AttributeValue userIdAttributeValue = userItemsMap.get("userId");
String userId = userIdAttributeValue.getS();
}
User item with valid entry
{ "subscribedTopics": [ "2", "5", "8", "1", "3", "4", "6", "7", "11" ], "userId": "Andrew.Green" }

Used combination of CONTAINS and OR and it worked.
ScanRequest scanRequest = new ScanRequest()
.withTableName("user")
.withFilterExpression("contains(subscribedTopics, :topic1) or contains(subscribedTopics, :topic2)")
.withProjectionExpression("userId")
.withExpressionAttributeValues(userAttributeValues);enter code here

Related

AWS Java SDK DynamoDB update expression for a "complex" item

So I have the following item where testId is the sort key:
{
"userId": "admin",
"testId": "1234",
"picture": "abstract",
"numOfUsers": 1,
"Tests": [
{
"duration": 1234,
"typeId": "2345",
"interval": 450000,
"quantity": 333333
},
{
"duration": 1234,
"typeId": "6789",
"interval": 450000,
"quantity": 333333
},
{
"duration": 1234,
"typeId": "2020",
"interval": 450000,
"quantity": 333333
}
]
}
As you can see, there are a few identical items under tests. My question is how do I update all of them with the same value? What I mean by that is that, for example, I would like to update duration on all three objects from 1234 to 2222.
Here is the code I've tested:
Table table = dynamoDB.getTable(tableName);
Map<String, String> expressionAttributeNames = new HashMap<String, String>();
expressionAttributeNames.put("#A", "Duration");
Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":val1", "2222");
UpdateItemOutcome outcome = table.updateItem(
"testId",
"1234",
"set #A :val1",
expressionAttributeNames,
expressionAttributeValues);
Any help would be appreciated :)
Based on my understanding of DynamoDb and Expressions, is that you need to tell dynamodb to drill into the attribute you want.
Your code is telling it to update Duration...but where is Duration? It is not at the top level of the item.
See if this would work:
Table table = dynamoDB.getTable(tableName);
Map<String, String> expressionAttributeNames = new HashMap<String, String>();
expressionAttributeNames.put("#Dur", "duration");
expressionAttributeNames.put("#Test", "Tests");
Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":val1", "2222");
UpdateItemOutcome outcome = table.updateItem(
"testId",
"1234",
"set #Test.#Dur :val1",
expressionAttributeNames,
expressionAttributeValues);
=== Edited ===
ValueMap valueMap = new ValueMap().withNumber(":dur", 2222));
UpdateItemSpec updateItemSpec = new UpdateItemSpec()
.withPrimaryKey("key", year)
.withUpdateExpression("set Tests.duration = :dur")
.withValueMap(valueMap)
.withReturnValues(ReturnValue.UPDATED_NEW);
UpdateItemOutcome updateItemOutcome = table.updateItem(updateItemSpec);
=== Edited ====
UpdateItemSpec updateItemSpec = new UpdateItemSpec()
.withPrimaryKey("key", "primaryKey")
.withUpdateExpression("set Tests.#duration = :value")
.withNameMap(new NameMap().with("#duration", "duration"))
.withValueMap(new ValueMap().withNumber(":value", 2222))
.withReturnValues(ReturnValue.UPDATED_NEW);

Given a set of sets, how to efficiently find sets that have at least 1 member in common?

Let's say we're given a set of sets, for example:
Set<String> s1 = Set.of("1", "2", "3", "4", "5", "7");
Set<String> s2 = Set.of("10", "20", "30", "40", "50");
Set<String> s3 = Set.of("100", "200", "300", "400", "500", "7", "9");
Set<String> s4 = Set.of("1000", "2000", "3000", "4000", "5000");
Set<String> s5 = Set.of("100000", "200000", "300000", "400000", "500000", "9");
How to find the collection of sets where there is member intersection? In this example, s1 and s3 have overlap as do s3 and s5.
The inefficient solution would be to
List<Set<String>> sets = List.of(s1, s2, s3, s4, s5);
for (Set<String> tester : sets) {
sets.remove(tester);
for (String s: tester) {
for (Set<String> target : sets) {
if (target.contains(s)) {
// record match
}
}
}
Can a better time complexity be acheived?

Not getting JSON data in the order in which i have entered

I am fetching details from a database table which contains 3 rows in JAVA.
I am using JSONarray and JSONObject as follows
JSONObject jsonObject = new JSONObject();
JSONObject mainjsonObject = new JSONObject();
JSONArray ja=new JSONArray();
The data from table is put to the jsonObject as follows for each one:
String qry="select * from details";
ResultSet res = select .executeQuery(qry);
while(res.next){
String Name=res.getString("name");
String age=res.getString("age");
.
.
jsonObject.put("Name", Name);
jsonObject.put("age", age);
.
.
ja.put(jsonObject);
}
mainjsonObject.put("PERSONAL DETAILS",ja);
I should get the output json as follows(i.e. the order in which i entered):
{
"PERSONAL DETAILS": [
{
" name": "abc",
"age": "4",
"gender": "F",
"Place": "abc1"
},
{
" name": "xyz",
"age": "3",
"gender": "M",
"Place": "abc2"
}
]
}
But am getting the values in random order like below:
{
"PERSONAL DETAILS": [
{
"age": "4",
" name": "abc",
"Place": "abc1"
"gender": "F",
},
{
"age": "3",
" name": "xyz",
"Place": "abc2"
"gender": "M",
}
]
}
Please help me with a solution. I need to get all the values in the same order in which i have entered.
You can try something like this to build json object construct using LinkedHashMap and then pass it to the constructor like this ,
LinkedHashMap<String, String> jsonOrderedMap = new LinkedHashMap<String, String>();
jsonOrderedMap.put("Name", res.getString(1));
...
...
// struct you want
JSONObject JSONorder = new JSONObject(jsonOrderedMap);
JSONArray sortedJSON = new JSONArray(Arrays.asList(JSONorder));

How do i refactor one JSON array into other format in JAVA?

I have a JSON array like this,
JSONArray content=
"[
{"+"\"pageid\":\"19\","+"\"company\":"+"\"C1\","+"\"pageview\":"+"\"10\","+"\"visitfreq\":"+"\"2\"},{"+"\"pageid\":\"19\","+"\"company\":"+"\"C2\","+"\"pageview\":"+"\"20\","+"\"visitfreq\":"+"\"4\"},{"+"\"pageid\":\"200\","+"\"company\":"+"\"C3\","+"\"pageview\":"+"\"30\","+"\"visitfreq\":"+"\"3\"}
]";
Code for JSONArray:
JSONObject jObj1 = new JSONObject();
jObj1.put("pageid", "19");
jObj1.put("company", "C1");
jObj1.put("pageview", "10");
jObj1.put("visitfreq", "2");
JSONObject jObj2 = new JSONObject();
jObj2.put("pageid", "19");
jObj2.put("company", "C2");
jObj2.put("pageview", "20");
jObj2.put("visitfreq", "4");
JSONObject jObj3 = new JSONObject();
jObj3.put("pageid", "200");
jObj3.put("company", "C3");
jObj3.put("pageview", "30");
jObj3.put("visitfreq", "3");
JSONArray jArr = new JSONArray();
jArr.put(jObj1);
jArr.put(jObj2);
jArr.put(jObj3);
Visual representation:
[
{
"company": "C1",
"visitfreq": "2",
"pageview": "10",
"pageid": "19"
},
{
"company": "C2",
"visitfreq": "4",
"pageview": "20",
"pageid": "19"
},
{
"company": "C3",
"visitfreq": "3",
"pageview": "30",
"pageid": "200"
}
]
I have worked on it to get an out put like below
the out put like this
[{pageid},[{rest of details}] ,{pageid},[{rest of details}] ]
if same pageid occur more than once
it should be like this
[{pageid},[{rest of details1},{rest of details2},.. ],{pageid},[{rest of details}] ]
Looks like you need to create a Map that maps pageid : [{rest of details1},{rest of details2},.. ].
Once you have that Map, you can transform it into your desired output.
Here is the code that will take your JSONArray (the one in the code above) and turn it into Map<String, JSONArray>.
public Map<String, JSONArray> getJsonArrayAsMapOnPageId(JSONArray inputArr) throws JSONException {
//Map holding pageid : [{company:"",pageview:"",visitfreq:""}, ... , ...] mappings
Map<String, JSONArray> idMap = new HashMap<String, JSONArray>();
for (int i=0; i < inputArr.length(); i++) {
JSONObject inputObj = inputArr.getJSONObject(i);
String id = inputObj.getString("pageid");
JSONArray jObjList;
if (idMap.containsKey(id)) {
//append to existing list in the Map
jObjList = idMap.get(id);
} else {
//create new list
jObjList = new JSONArray();
}
JSONObject newJsonObj = new JSONObject();
newJsonObj.put("company", inputObj.get("company"));
newJsonObj.put("pageview", inputObj.get("pageview"));
newJsonObj.put("visitfreq", inputObj.get("visitfreq"));
jObjList.put(newJsonObj);
idMap.put(id, jObjList);
}
return idMap;
}
Here is what it'll look like:
System.out.println("Map looks like:\n" + pageidMap);
Here is what I got:
{
200=[
{
"company": "C3",
"visitfreq": "3",
"pageview": "30"
}
],
19=[
{
"company": "C1",
"visitfreq": "2",
"pageview": "10"
},
{
"company": "C2",
"visitfreq": "4",
"pageview": "20"
}
]
}
I'm not sure exactly in what form (Object, print to output, etc) you want this output to be in, so you can do the final bit of transforming this Map<String, JSONArray> into [{pageid},[{rest of details1},{rest of details2},.. ],{pageid},[{rest of details}] ] without problems.

Inserting object with different values in a ArrayList

I have a JFrame where I insert some informations, these informations I send to a object called "macro". When I hit a JButton "macro" is insert in a ArrayList, called "listaJFP". When I enter with the first informations like, name "Murilo", id "1", and hit the button, my ArrayList receives the correct information, but when I try to insert another name like "Joao", id "2", my ArrayList receives in the first index [0] Joao, 2, and second index[1] Joao, 2. Instead of [0]Murilo,1 and [1]Joao,2. I looked for this problem and I saw someone talking about the reference of the object, in other words, when I change the values of my object "macro" at the same time the values of my ArrayList are changed. Can someone help me, please ? Thanks for the attention !
This is in my class JFramePrincipal:
Macro macro = new Macro();
private List<Macro> listaJFP = new ArrayList<Macro>();
This is in my JButton actionPerformed:
listaJFP.add(macro);
JFrameTabela jfT = new JFrameTabela(listaJFP);
I will try to put more code:
public class JFramePrincipal extends javax.swing.JFrame {
private List<Macro> listaJFP = new ArrayList<Macro>();
Macro macro = new Macro();
String[] arrayNodeName;
String[] listaVelocidade = new String[]{"1024", "1984"};
String[] listaSlot = new String[]{"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13"};
String[] listaModule86x0 = new String[]{"0", "1"};
String[] listaModule8609 = new String[]{"3", "4"};
String[] listaPort = new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"};
String[] listaPortFeGe = new String[]{"0", "1", "2", "3", "4", "5", "6", "7"};
String[] nodeType = new String[]{"8609", "8630", "8660"};
private void jButtonGerarMacroActionPerformed(java.awt.event.ActionEvent evt) {
try {
if (jCheckBoxFSP.isSelected() == true) {
macro.setVpnName(jFormattedTextFieldFSP.getValue().toString());
} else if (jCheckBoxSP.isSelected() == true) {
macro.setVpnName(jFormattedTextFieldSP.getValue().toString());
}
macro.velocidade = jComboBoxVelocidade.getSelectedItem().toString();
if (jTextVLAN.isEnabled() == true) {
int vlanInt;
boolean ok = false;
vlanInt = Integer.parseInt(jTextVLAN.getText());
do {
if (vlanInt >= 1 && vlanInt <= 4094) {
macro.vlan = jTextVLAN.getText();
gerar();
jButtonExecutarMacro.setEnabled(true);
} else {
JOptionPane.showMessageDialog(null, "VLAN deve ser maior do que 0 e menor do que 4094", "Mensagem", JOptionPane.ERROR_MESSAGE);
jTextVLAN.grabFocus();
jButtonExecutarMacro.setEnabled(false);
}
} while (ok);
} else {
macro.vlan = null;
gerar();
jButtonExecutarMacro.setEnabled(true);
jButtonGerarMacro.setEnabled(false);
}
private void jButtonExibirResultadoActionPerformed(java.awt.event.ActionEvent evt) {
if(jCheckBoxE1.isSelected() == true){
listaJFP.add(macro);
Macro macro = new Macro();
JFrameTabela jfT = new JFrameTabela(listaJFP);
}
Did you make sure to create a new Macro for every input from GUI
You have to Create a new Macro like this
public void actionPerformed(ActionEvent e){
Macro macro = new Macro();
listaJFP.add(macro);
}
// so it create a totally new Macro object everytime
Edit: After OP edit with more code
You need to create to new Macro inside to the first ActionPerformed because that's where you're manipulating the data. And why do you have two different actionperformed for a similar task?

Categories