I am trying to query DynamoDB using mapper.query() function with FilterExpression.
I need to generate a generic function where I will just tell the attributes operator and value, and it will return the generic string. But I see, it is not completely possible.
new DynamoDBQueryExpression<T>()
.withFilterExpression("att = string_val")
This is possible but if I have an Integer filter, then I have to do like this :
new DynamoDBQueryExpression<T>()
.withFilterExpression("att = :filter")
.withValueMap(":filter", new AttributeValue().withN(String.valueOf(12)));
Can this be avoided ? I wish to put everything in the filter string.. Can dynamoDB itself recognise int/string attributes ?
Thanks in advance!
Related
I want to design an update function for my DynamoDB table that only updates the record when the hash key and range key pair is in the DynamoDB table. If the item doesn't exist, I would like to throw a badRequestError. How can I use a DynamoDB expression to achieve this? Can I set both the expectedAttribute to true and set the conditional operator to AND?
If you are using DynamoDBMapper you could use DynamoDBSaveExpression
Something like:
Map<String, ExpectedAttributeValue> expected =
Map.of("hashKeyAttrName", new ExpectedAttributeValue().withExists(true),
"rangeKeyAttrName", new ExpectedAttributeValue().withExists(true));
DynamoDBSaveExpression expression = new DynamoDBSaveExpression();
expression.setExpected(expected);
dynamoDBMapper.save(item, expression);
If condition is not met save will trow a ConditionalCheckFailedException
My rep is too low to comment ccamcmxc's answer, so I'll just give a new answer.
The additional thing you need is to provide AttributeValue for the ExpectedAttributeValue call to make the whole thing work. The complete code sample looks like below.
Map<String, ExpectedAttributeValue> expected = Map.of(
"hashKeyAttrName", new ExpectedAttributeValue(new AttributeValue(hashKey))
.withExists(true),
"rangeKeyAttrName", new ExpectedAttributeValue(new AttributeValue(rangeKey))
.withExists(true));
DynamoDBSaveExpression expression = new DynamoDBSaveExpression();
expression.setExpected(expected);
dynamoDBMapper.save(item, expression);
To add a little flavor to the recipe, the save method has an overload that supports you to also provide SaveBehavior as the third parameter which gives you even more control.
An example:
dynamoDBMapper.save(item, expression, UPDATE_SKIP_NULL_ATTRIBUTES.config());
Using the JOOQ parser API, I'm able to parse the following query and get the parameters map from the resulting Query object. From this, I can tell that there is one parameter, and it's name is "something".
However, I haven't been able to figure out how to determine that the parameter "something" is assigned to a column named "BAZ" and that column is part of the table "BAR".
Does the parser API have a way to get the table/column metadata associated to each parameter?
String sql = "SELECT A.FOO FROM BAR A WHERE A.BAZ = :something";
DSLContext context = DSL.using...
Parser parser = context.parser();
Query query = parser.parseQuery(sql);
Map<String, Param<?>> params = query.getParams();
Starting from jOOQ 3.16
jOOQ 3.16 introduced a new, experimental (as of 3.16) query object model API, which can be traversed, see:
The manual
A blog post about traversing jOOQ expression trees
Specifically, you can write:
List<QueryPart> parts = query.$traverse(
Traversers.findingAll(q -> q instanceof Param)
);
Or, to conveniently produce exactly the type you wanted:
Map<String, Param<?>> params = query.$traverse(Traversers.collecting(
Collectors.filtering(q -> q instanceof Param,
Collectors.toMap(
q -> ((Param<?>) q).getParamName(),
q -> (Param<?>) q
)
)
));
The Collectors.toMap() call could include a mergeFunction, in case you have the same param name twice.
Pre jOOQ 3.16
As of jOOQ 3.11, the SPI that can be used to access the internal expression tree is the VisitListener SPI, which you have to attach to your context.configuration() prior to parsing. It will then be invoked whenever you traverse that expression tree, e.g. on your query.getParams() call.
However, there's quite a bit of manual plumbing that needs to be done. For example, the VisitListener will only see A.BAZ as a column reference without knowing directly that A is the renamed table BAR. You will have to keep track of such renaming yourself when you visit the BAR A expression.
Disclaimer: I am new to MongoDB. I just started to use it few days back. Sorry if my question doesn't make much sense.
Hello,
I am trying to make a Query to MongoDB from Java method, I want to create and make a query only if that parameter is not null. So let us say that my method is
public List<Object> getSomethingFromMongoDB(String searchParameter){
Query query = new Query().addCriteria(Criteria.where("something").is((searchParameter)));
}
Now I only want to search when SearchParameter only when it is notNull. Can I do this in a better way? I tried to check $ne but cannot understand how to apply it in my Java method.
Thanks in advance
I would advise the following:
public List<Document> getSomethingFromMongoDB(List<String> searchParameters){
List<Document> results = new ArrayList<>();
if (searchParameters == null) return results;
Document criteria = new Document();
searchParameters.forEach(parameter -> criteria.append("yourField",parameter));
collection.find(criteria).iterator().forEachRemaining(results::add);
return results;
}
If the parameters list is empty, you will just get all the documents.
If not, the corresponding criteria will be applied.
You could even get rid of the null-checking line, by making sure you pass a new ArrayList() for example, instead of null.
There are two methods to filter realmResult in java by "string"
RealmResults data = realm.where(RasifalDTO.class).contains(keyString,valueString);
But what i want to do is filter the Result with Respect to integer so i tried:
RealmResults data = realm.where(RasifalDTO.class).contains(keyString,vauleInt+"");
But i get :
java.lang.IllegalArgumentException: Field 'rasifalType': type mismatch. Was INTEGER, expected [STRING].
If you want to filter the result by an attribute of the Realm Object which happens to be an integer. Then equalTo(String key,int value) is the way to go (Do not get confused with using contains(key string,value string) like i was ).
RealmResult data = realm.where(RasifalDTO.class).equalTo(keyString,valueInt).findAll();
Try using this:
RealmResults data = realm.where(RasifalDTO.class).contains(keyString,String.valueOf(vauleInt));
I want to create a Spring EL in which I want that two integers be concatenated as a-b with a and b being integers. Spring EL does not support concat function with integers as they are not Strings. I have tried to cast them like #T(java.lang.String).valueOf(user.id).concat('-').concat(#T(java.lang.String).valueOf(user.serviceId)) but this is not working.
What should be the correct expression?
Please, use next expression #{T(java.lang.String).format('%d-%d', user.id, user.serviceId)}.
Hope this helps.
Update.
If this expression will be used within #Cacheable(key) field, please update expression in next way: T(java.lang.String).format('%d-%d', #user.id, #user.serviceId).
I added it and it really works in java spring booot caches:
#Cacheable(cacheNames = ALL_CLASS_MKTU_BY_RESH_DATA, key = "{T(java.lang.String).format(\"%d-%d-%d\",#id,#year,#type)}")
public List<String> findAll(int id, int year, int type) {
//
}