All operator in mongo using Spring - java

How can I use #Query annotation in spring to query an array in mongo Document.
eg:
user_id : 1
tags : ['scientist','biologist','mathematician','chemist'];
user_id : 1
tags : ['scientist','physicist','carpenter','chemist'];
I am query making api and the URL is something like this:
localhost:8080/tags=scientist,biologist // should return 1st document
or
localhost:8080/tags=physicist,carpenter // should return 2nd document
There can be any number of tags in the url and the tag array must contain all the tags present in the url.
How can I acheive this?

You could try the query annotation which uses the $or operator as
#Query("{'$or' : [{ 'tags': ?0, 'tags': ?1 }]}")
public List<Tags> findByTagsFirstorSecond(string firstTag, string secondTag);

Related

JpaRepository make a query to select all element that contains the array of tags

I have a postgres db table named "challenge" which contains a 'tags' text column in that each tags of the challenge is stored as "tag1,tag2,tag3...".
So I need to make a request that can check if a challenge contains all tags in the provided array but I don't know how to make this.
My repository method:
#Query(?)
Page<Challenge> findByTags(String[] tags, Pageable pageable);
What i've done so far it's a query which works with one tag but not with an array:
SELECT * FROM challenge WHERE tags LIKE '%' || :tag || '%';

Is there such a query for mongodb?

I need to do a query on mongoDB due to I am developing in Java with Spring Boot and MongoDB. I know that this command is for arrays:
#Query("{ 'skills' : {$all : ?0}} ")
List<DataCV2> findAllSkillsInCV(ArrayList<String> skillsOfCV);
This query let me to find if all fields of the arraylist "skillsOfCV" are in the arraylist called "skills"
However, I am trying to pass an arraylist as "skillsOfCV" to compare all the fields with a string field in database.
#Query("{ 'experienceCV' : {$all : ?0}} ")
List<DataCV2> findAllExperienceInCV(ArrayList<String> experienceOfCV);
The field "experienceCV" is a string one, and I want to compare if this string field contains all the fields of the arraylist "experienceOfCV".How could I do that?
It is not possible to match String and List<String> using $all in a straightforward way.
The best bet is that use String field for the method and do the conversion programmatically.
Or else you can give a try with aggregation framework which has many useful aggregation operators.

Get Elasticsearch match based on list of values

I'm using Logstash to input data from my database to Elasticsearch.
For an specific SQL query, I have one column that retrieves values as a CSV, like "role1;role2;role3".
This column is being indexed as a regular string in Elastic.
The problem:
I need to make an Elastic query on that field based on another list of values.
For example: On the java side I have a collection with the values: "role3", "role4", "role5" and based on that I should get all the records in Elastic that matches "role3", "role4" or "role5".
In this specific case, my elastic data is like this:
"_source": {
"userName": "user1",
"roles": "role1;role2;role3"
}
"_source": {
"userName": "user2",
"roles": "role7;role8;role9"
}
In this case it should return the record for "user1", as it gets a match for the "role3".
Question:
What is the best way to do that ?
I can make a query using something like the LIKE operator for all itens of my java list:
//javaList collection has 3 items: "role3", "role4" and "role5"
for (String role: javaList) {
query = QueryBuilders.boolQuery();
query.should(QueryBuilders.wildcardQuery("roles", "*" + role + "*"));
response = client.prepareSearch(indexName).setQuery(query).setTypes(type).execute().actionGet();
hits = response.getHits();
}
And then iterate over each hit, but this sounds like a very bad apporach, because the javaList can have more than 20 itens, that would mean 20 querys to elastic.
I need a way to tell this to Elastic:
This is my list of roles, query internally and retrieve
only the records that matches at least one of those roles.
In order to do that I understand I can't index that data as a String right ? Ideally would be to have it an array or something like it...
How can I do that in the most performatic way ?
Definitely you should not use wildcard query in a loop. This solution eventually will demonstrate a poor performance.
Since roles field is a regular text field Elasticsearch splits value "role1;role2;role3" into individual tokens "role1", "role2" and "role3". The same operation is applied to a search query. You can use simple match query with query string "role3;role4;role5" and get hit because of "role3" token match.
Also you can index roles field as an array of strings and the same match query will still work.

How to retrieve and remove embedded document spring data mongodb

There I am stuck, how to remove embedded document in mongodb. I am using spring data mongodb criteria, I am doing it like the following:
// database
"_id" : ObjectId("55683d51e4b0b6050c5b0db7"),
"_class" : "com.samepinch.domain.metadata.Metadata",
"preferenceType" : "SHOPPING",
"subtypes" : [
{
"_id" : ObjectId("55683d51e4b0b6050c5b0db6"),
"leftValue" : "VEG",
"rightValue" : "NON_VEG",
"preferencePoint" : 0
}
],
"createdDate" : ISODate("2015-05-29T10:20:01.610Z"),
"updatedDate" : ISODate("2015-05-29T10:20:01.610Z")
// query
mongoTemplate.updateMulti(new Query(),
new Update().pull("subtypes", Query.query(Criteria.where("subtypes._id").is(new objectId("55683d51e4b0b6050c5b0db6"))),Metadata.class);
What i am doing wrong?
Thanks in advance!
subtypes is in nested objects so you should first pass this in $elemMatch is matched first matching array elements of given conditions. Update query as :
db.updateMulti.update({"subtypes":{"$elemMatch":{"_id":ObjectId("55683d51e4b0b6050c5b0db6")}}},
{"$pull":{"subtypes":{"_id":ObjectId("55683d51e4b0b6050c5b0db6")}}})
this query pull exact matching array elements from subtypes array .
And with the help of this spring elemMatch ( not that much expertise in spring mongo ) I converted this query in spring format as below :
mongoTemplate.updateMulti(new Query(
where("subtypes").elemMatch(where("_id").is(ew objectId("55683d51e4b0b6050c5b0db6"))).pull(
pull("subtypes", Query.query(Criteria.where("_id").is(new objectId("55683d51e4b0b6050c5b0db6"))),Metadata.class
));
this above spring query not tested I hope you will convert mongo update query in spring mongo query format.

ObjectId in mongoDB 2.6 not working

I'm using spring data mongodb in my application. It uses mongodb 2.6. I want to query documents of a collection by the id which mongo assigns during insertion. I'm doing something like this:
Query query = new Query();
String id = "542385a91f00bf7dbeae1fc7";
query.addCriteria(Criteria.where("_id").new Object(id));
template.find(query, entity.class);
This query translates to:
{ "_id" : { "$oid" : "542385a91f00bf7dbeae1fc7"}}
When I execute the same on mongo shell, it gives an error:
error: {
"$err" : "Can't canonicalize query: BadValue unknown operator: $oid",
"code" : 17287
}
How do I query by id using spring data mongodb?
It should read
new ObjectId(id)
instead of new Object(id). Please see the API docs for details.

Categories