Is there such a query for mongodb? - java

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.

Related

MongoDB how to find all documents who's array contains a specific string?

Below is an example of my "Event" document in MongoDB. I want to be able to query all of the Event documents where the attendees array contains "623d03730e82c57fefa52fb2" (a user ID).
Here is one of my event documents:
_id: ObjectId(623ce74372a28f08dea6c959)
description: "Fun BBQ to celebrate my 21st!"
host: "623d03730e82c57fefa52fb2"
invitees: Array
location: "My address..."
name: "Fun Birthday BBQ"
private: true
date: "03/28/22"
end: "11:15 PM"
start: "06:35 PM"
attendees:Array
0: "623d03730e82c57fefa52fb2"
Here is my broken query code:
String id = "623d03730e82c57fefa52fb2";
// I have also tried Document queryFilter = new Document("attendees", id);
Document queryFilter = new Document("attendees", new Document("$in", Arrays.asList(id)));
The above code always returns an empty result. To clarify I am using Java and MongoDB Realms but that shouldn't matter.
You don't need $in, use only $eq is ok.
db.collection.find({
attendees: "623d03730e82c57fefa52fb2"
})
mongoplayground
For easier and more efficient queries, it's important that the types of field values remain consistent.
For example, if "_id" is stored at an ObjectId, then query parameters should also be of type ObjectId. Likewise, if they are strings, then consistently use strings.
If different value types are stored for individual field values, successful queries can still be possible, but not as efficiently since the field types must be considered in the queries. For example, if trying to find a doc by a field that may have a string or an ObjectId type, the query must either search for both types, or the query writer must know the type beforehand. It's easier and more efficient to just pick one type for a field and stick to it.

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.

Mongo Java - prefexing a field value with some constant in all the docs

I have so many documents in a collection and would like to change one of the filed name in all the documents. Also, want to change the value with some prefixed constant in all the docs.
Example,
{
"_id" : ObjectId("56e9e6e9083378ba4e5e8832"),
"name" : "Mike"
}
Should be changed to,
{
"_id" : ObjectId("56e9e6e9083378ba4e5e8832"),
"firstName" : "First-Mike"
}
I used the following Java code to rename the field,
final MongoDatabase mongoDb = mongo.getDatabase(database);
final MongoCollection<Document> collection = mongoDb.getCollection("<CollectionName>");
Bson rename = Updates.rename("name", "firstName");
collection.updateMany(new Document(), rename);
But not sure, how to change the value with some prefixed constants for all the documents in the collection.
I can iterate all the documents in the collection and do the change, but trying to understand, if there is any way we can do this without iterating all the documents, like single update.
Thanks
Why not use regular expressions for prefix matching? A single update command can do your job if you use mongodb's regex:
https://docs.mongodb.org/manual/reference/operator/query/regex/

hibernate Query to find record based on substring

I want to make a Hibernate query to check if a string contains a substring.
Suppose a user class having id,name,info.
info is String which contain multiple substrings.
For example info contains strings like "hi I am from Pune".
I want to read all record which contain Pune as substring.
I tried using like query but not working.
Criteria criteria = session.createCriteria(Post.class);
criteria.add(Restrictions.like("content",contentStringToLook));
users = (List<Post>)criteria.list();
Try modifying the restriction as follows:
criteria.add(Restrictions.like("content","%"+contentStringToLook+"%"));
You can use this :
criteria.add(Restrictions.like("content",contentStringToLook, MatchMode.ANYWHERE))
There's also MatchMode.START, .END, and .EXACT.

Hibernate Restrictions.in() only accepts propertyName as String

I have a List of ids:
List<Object> ids;
I need to use this in a criteria query to get all rows with an id that ids contains.
What I have now and works:
if (ids.size() > 0) {
for (Object id : ids) {
preparedResults.add((T)sessionMngr.getSession().
createCriteria(rowType).add(Restrictions.idEq(id))
.uniqueResult());
}
}
So I fetch them one by one, which isn't optimal, but I first tried something like following to get them in one query, but don't know what to put at the ???:
preparedResults.addAll(sessionMngr.getSession().
createCriteria(rowType).
add(Restrictions.in(???, ids)).list());
The first argument of Restrictions.in() is of type String. I can't put a hard coded "id" there as I don't know what the propertyname is.
So I don't know how to get the id property as a String there.
I saw Projections.id(), but I am not sure if I can use this to get it as a String.
With this solution you can retrieve the name of the id field of your entity. If you use annotations you can have it even shorter as described here. If you donĀ“t use composite primary keys you could also use
ClassMetadata classMetadata = getSessionFactory().getClassMetadata(myClass);
string identifierPropertyName = classMetadata.getIdentifierPropertyName();
Source of this snippet: here

Categories