SQL IN equivalent in DynamoDb in java - java

I have been given a task to return the data for a list of items whose ids I have. The table has an id defined as:
...
"KeySchema" [
0: {
"AttributeName":"id"
"KeyType":"HASH"
"TableStatus":"ACTIVE"
I have a list of say 100 of these ids and want to query to return the details in a similar way to how IN works in SQL.
I have tried many approaches but cant see a way I can make a single query to the DynamoDB instance where it will return all documents for the Ids in a supplied list.
I hope to use DynamoDBMapper.
I thought I'd hit the jackpot when I found withHashKeyValues on DynamoDBQueryExpression.
e.g.
DynamoDBQueryExpression<MyObject> ddqe;
...
for (String idStr : idList) {
MyObject mo= new MyObject();
mo.setId(idStr);
ddqe.withHashKeyValues(mo);
}
but looking at the code although the method is plural there is a note that says:
Note 1: Currently the DynamoDBMapper supports only one value per hash key.
I have also tried a Condition (amongst many other things)
Condition condition = new Condition();
condition.withAttributeValueList(filters);
condition.withComparisonOperator(ComparisonOperator.EQ);
Where filters is an ArrayList of the ids.
Is there a way to do this in DynamoDb or have I got to query the DB for every known id individually, e.g. issue 100 query's to the data store?

Queries start at a particular Partition key, so you would have to look up one key at a time with the Query API. Instead, you could use the BatchGetItem API and request 25 items a time.

Related

Fetching a record from an arraylist that is made up of arrays of objects

I have a java arraylist that is made like this:
{[{},{}], [{},{}], [{},{}], [{},{}]} of around four thousand records.
I have a particular key through which I want to search in one of the objects in this list and fetch that particular array where that
record matches. The search key is a string.
Is there a solution to this without traversing through the entire list.
It is basically a list that is constructed like this:
List<Object[]> list = new ArrayList<>();
I am using this to fetch the the data from two tables using a join. Individual records of each tables map to these objects.
Say table1: {a:1,b:2,c:3} and table2: {x:1,y:2,z:3}
the data returned would be
{[{a:1,b:2,c:3}, {x:1,y:2,z:3}],[{a:2,b:3,c:4}, {x:2,y:3,z:4}]}
How will I search for say in which array in the list is a=2.
Thanks
If you do not want to be a victim of the linear search, you should consider using another type of data structure than List.
The use case you described seems like a good match for a Map in general. If you want constant time key lookup, consider using HashMap instead.

JDBC One To Many Joins vs Multiple Selects

I am currently writing a program for which I need to select an entity from the database which has multiple one to many relationships. In this program the main object a Route is made of many Route Points has many Comments and many Reports. This means if i want to select a Route from the database along with its Route Points, Comments and Reports as a result of the join I am going to get multiple rows back with duplicate information in.
As far as I am aware this will mean I will have to loop on each row and keep a set of if I have already "seen" this RoutePoint, Report or Comment. As a Route can have a large number of Route Points I imagine this would be quite slow as well as been quite complicated and messy. I have included below what this would look like.
HashSet<String> commentIds = new HashSet<String>();
HashSet<String> routePointIds = new HashSet<String>();
HashSet<String> reportIds = new HashSet<String>();
Route route = null;
while (resultSet.next()) {
String commentId = resultSet.getString("commentId");
String routePointId = resultSet.getString("routePointId");
String reportId = resultSet.getString("reportId");
if(route == null){
// create route from result set
}
if(!commentIds.contains(commentId)){
// create comment object from result set
// add to route object
commentIds.add(commentId);
}
if(!routePointIds.contains(routePointId)){
// create route point object from result set
// add to route object
routePointIds.add(routePointId);
}
if(!reportIds.contains(reportId)){
// create comment object from result set
// add to route
reportIds.add(reportId);
}
}
My question is, is there a simpler way of processing a query with multiple one to many joins in JDBC?
Another way I have thought of approaching this is to do multiple selects. One for each table rather than joining. I am not sure if this is a suitable way to do this as it would mean querying the database multiple times rather than just the once.
Thanks for your replies.
Query for distinct rows for each independent result set. Since you are only querying for one route's data, I'm assuming you are not storing this in a cache or memory, and will need to perform this action any time you need the route data. It will more efficient to use an optimized query, and avoid java logic for each row returned to weed out duplicate data.

JPA Re executing same namedQuery with different parameters

I'm using openJPA as implementation, and i'm facing the following issue.
In one of our services, we use a namedQuery to select value in a range, so something like that:
query = "select xxx from xxx where xxx in (:param)"
This service / query is called by another process which is responsible of building/providing this parameter value. Sometime - for bad reasons - this process give us a list with a length greater than the maximum one authorized by DB2.
So i'm wondering if it's possible for us to implement a mecanism to automatically split this parameter into several list of vlaues, execute for each internal list this namedQuery and then aggregate results before returning.
The main question now is: can i re-use several times my built TypedQuery to re-execute same request but with a different parameter value ?
Code example (For the example, not a real nor existing code):
TypedQuery<MyClass> query = em.createNamedQuery("myQueryName", MyClass.class);
foreach (...) {
query.setParameter(...);
res = query.getResultList();
// Query re-executed and results are different ?
}
Is it a correct way to fix this kind of issue, if not is there any better (in term of performances) way to do this ?
No, you can't do that. You must recreate the TypedQuery for each execution.

Ordering post in list by atribute java

Is possible to order elements in List indirectly (in Java 7)? Assume having elements of list which are post which have atributs (atributs of type Post) id, text, timestamp (millisec from 1970 - just number type long).
The posts are stored in database (MySQL) and they came as result of different SELECTs. It's because posts is something tweets on twitter - posts which added user, posts of users which user follows and maybe some others. The idea is do some SELECTSs, each get result as list and these lists will be added to one list, which I want to order by atribute (timestamp). Is any easy way to sort it indirectly (from higher to lower - to have newest to oldest posts) by this atribute (timestamp)? I know that List have attribute sort and I should probably do something with that.
You probably want to use a Set, and more specifically a SortedSet (the basic implementation of it being a TreeSet), instead of a List. This will require that your post class implement Comparable of itself, however.
Of course, there is always the option to ORDER BY at the database level. This way you can use a classical List.
You can query the database using Order By clause to get the result in order of timestamp, then you won't have to do sorting at java side.
There are two ways to do it. You can do it from query by using ORDER BY column or use comparable and comparator to sort objects. link =
http://www.mkyong.com/java/java-object-sorting-example-comparable-and-comparator/

PlayFramework get field from model select

Since the play documentation on models is terrible I'll ask here. I have the basic code;
public static void Controller() {
List<Item> item = Item.find("SELECT itemname,id FROM Item WHERE itembool = true ORDER BY itemcreated ASC LIMIT 0,1").fetch();
if ( item == null ) {
notFound();
}
}
What I'm trying to do is get the value for 'itemname' returned for the first value returned from an SQL query (The real query is much more complicated and other things so it can't be replaced with methods). I can get the entire first object with item.get(0) but I can't figure out how to get the value of 'itemname' as a string and it doesn't seem to be documented anywhere.
Edit
Probably should have mentioned in the original question, I need to retrieve by field name, not index. I.E. I can't do items.get(0)[0]; I need to do items.get(0)['itemname'];
The documentation explains this if you read it, in here. Hibernate doesn't use SQL, but JPQL, which has a different syntax as it works with objects, not individual fields.
What you want to do can be achieved in two ways (both in the documentation):
List<Item> item = Item.find("SELECT i FROM Item i WHERE i.itembool = true ORDER BY i.itemcreated ASC").fetch(1);
List<Item> item = Item.find("itembool = true ORDER BY itemcreated ASC").fetch(1);
EDIT:
On the retrieval part, you will get a list of Item, so you can just access the field directly on the object:
item.get(0).getItemName();
Since Play uses Hibernate under the hood, you need to take a look at Hibernate's documentation.
In particular, SELECT itemname,id ... yields Object[] rather than Item, so that you can get itemname as follows:
List<Object[]> items = ...;
String itemname = items.get(0)[0];
well if you have to do a select itemname,id ..., you would not be able to do a items.get(0)["itemname"] because as axtavt and Pere have mentioned, you would get a Object[] back. You can instead create another (perhaps immutable) entity class that can be used in this query. Please refer to hibernate documentation for details. You can then model the entity based on your query requirements and use it to fetch information, thus letting hibernate handle all the magic number game for you. That ways, you would have a bean with filled up values that you can use to map back to your model class if you like.
HTH!

Categories

Resources