MongoDB query for value in field with regex using Java - java

I am trying to query from my collection of documents which looks like:
{ "_id" : ObjectId("94"), "EmailAddress" :"adam#gmail.com","Interests": "CZ1001,CE2004" }
{ "_id" : ObjectId("44"), "EmailAddress" :"ben#gmail.com", "Interests":"CE1001,CE4002" }
{ "_id" : ObjectId("54"), "EmailAddress" :"chris#gmail.com","Interests":"CE1001,CE2002" }
An example is that i want to retrieve the email addresses, given that the field "Interests" has that value i am looking for.
Example if i search CZ1001, i will get back Obj 1 EmailAddress details.
If i search CE1001, i will get back Obj 2 and Obj 3 EmailAddress details.
The object id are uniquely created when i inserted records at the start if that helps.
I am able to get the objects on MongoDB Shell using
db.users.find(Module: {"$regex": "CE1001"}})
Only the email addresses are needed.
I am trying to get all the email addresses and got stuck at this code.
Document doc = (Document) collection.find(new BasicDBObject("Module", {"$regex":"CE1001"})) .projection(Projections.fields(Projections.include("EmailAddress"), Projections.excludeId())).first();
Where
new BasicDBObject("Module", {"$regex":"CE1001"}) is not allowed.
new BasicDBObject("Module", String_variable) is allowed

For a particular Interest, your mongoDB query would look like(taking CE1001 as an example):
db.collection.find({
$or: [
{
Interests: {
$regex: "^CE1001,"
}
},
{
Interests: {
$regex: ",CE1001,"
}
},
{
Interests: {
$regex: ",CE1001$"
}
}
]
},
{
"EmailAddress": 1
})

For others who happens to drop by this post. Below are the working codes. Credits to #Veeram.
FindIterable <Document> results = collection.find(new BasicDBObject("Module", new BasicDBObject("$regex", "CE1001")) .projection(Projections.fields(Projections.include("EmailAddress"), Projections.excludeId()));
for(Document doc : results) {
doc.getString("EmailAddress")
}

Related

How to ignore duplicate field values while inserting duplicates in Mongodb with Java syntax

I am able to insert the documents in mongodb collection but but it is inserting the duplicate values in collection .How to avoid the duplicates field value ("System.UniqueNumber") in java :Document looks like below .I need check the System.UniqueNumber value ,in case if any value is existing ,document should not be inserted to database. I tried with upsert oepration but it is not happening . Can anyone help how to ignore the duplicates in java .
{
"_id" : ObjectId("abedfg"),
"Amoun" : {
"Type" : {
"key" : "dollar",
"value" : "system"
},
"System" : {
"UniqueNumber" : "123",
"color" : "Red",
},
public boolean create(#Valid #RequestBody Document... documents) {
MongoDatabase database = this.mongoClient.getDatabase("Database");
MongoCollection<Document> collection = database.getCollection("Database");
List<Document> documentList = new ArrayList<>(bookings.length);
for (Document doc: documents) {
documentList.add(Document.parse(booking.toJson()));
}
collection.insertMany(documentList);
}

How perform query that delete elements from nested array in MongoDb using Morphia?

I have the following mongoDB object
{
"_id" : ObjectId("5c3f32a4e17c5739bccb9115"),
"name" : "John",
"friends" : [
{
"name" : "Paul"
},
{
"name" : "Lisa"
}
]
}
I need to delete some element from it. In native mongodb query it looks like
db.users.update({}, {$pull: {friends: {name:"Lisa"}}})
But how can I do this via Morhia API?
I resolve this issue by using:
Query<Group> query = getDatastore().createQuery(Group.class);
UpdateOperations<Group> ops = getDatastore().createUpdateOperations(Group.class)
.removeAll("friends", new BasicDBObject("name", "Lisa"));
getDatastore().update(query, ops);

Elasticsearch multilevel object search Java

I have a document given below.
{
"my_id": "123",
"content": {
"name": "abc",
"designation": "engineer"
}
}
I have written Java code for elasticsearch to access the field name which is given below.
String field = "content.name";
String value = "abc"
SearchResponse response = esClient.prepareSearch("indexName")
.setTypes("data")
.setQuery(QueryBuilders.matchQuery(field, value))
.get();
But the output that I am getting for this multilevel object search empty hits. Is there a way to access multilevel objects in Java
The given query works from sense.
GET indexName/_search
{
"query" : {
"match" : {
"content.name" : "abc"
}
}
}

MongoDB compare document fields in aggregation pipeline

I have a collection of documents like the following:
{ name : "John" ,
age : 25.0 ,
bornIn : "Milan" ,
city : [ {
name : "Roma" ,
state : "IT" ,
mayor : "John"
}]
}
{ name : "Jim" ,
age : 35.0 ,
bornIn : "Madrid" ,
city : [ {
name : "Madrid" ,
state : "ESP" ,
mayor : "Jim"
}]
}
I want to retrieve all the documents that have the field $bornIn equal to the field $city.name. I need to do this as an intermediate stage of a pipeline, so I can't use the $where operator.
I searched online and I found a suggestion to implement something like this:
{ $project:
{ matches:
{ $eq:[ '$bornIn', '$city.name' ] }
}
},
{ $match:
{ matches:true }
} )
But it didn't work neither via shell nor via Java driver as it marks the fields as different.
For the sake of completeness I report my code:
final DBObject eq = new BasicDBObject();
LinkedList eqFields = new LinkedList();
eqFields.add("$bornIn");
eqFields.add("$city.name");
eq.put("$eq", eqFields);
projectFields.put("matches", eq);
final DBObject proj = new BasicDBObject("$project", projectFields);
LinkedList agg = new LinkedList();
agg.add(proj);
final AggregationOutput aggregate = table.aggregate( agg);
Do you have any suggestion? I'm using MongoDB 3.2, and I need to do this via Java Driver.
Thanks!!
PS. It is not relevant but actually the documents above are the output of a $lookup stage among collections "cities" and "persons", with join on $name/$mayor.. it is super cool!! :D :D
I'm a little rusty on how Mongo deals with deep equality searching arrays of objects, but this is definitely doable with $unwind
db.foo.aggregate([
{$unwind: "$city"},
{ $project:
{ matches:
{ $eq:[ '$bornIn', '$city.name' ] }
}
},
{ $match:
{ matches:true }
}
]);
I'm not on a computer with Mongo right now, so my syntax might be off a bit.

Complex MongoDB find queries on large documents in Java

How do I make a MongoDB query using BasicDBObjects in Java, when I wish to find all documents that contain an array of nested documents, where one of those nested documents meets all the specified criteria?
Taking the example data:
[
{
"_id":"blood_0",
"type":"O",
"list":[
{
"firstname":"John",
"lastname":"Smith",
"zipcode":"12345"
},
{
"firstname":"John",
"lastname":"Hamilton",
"zipcode":"54627"
},
{
"firstname":"Ben",
"lastname":"Brick",
"zipcode":"12345"
},
{
"firstname":"William",
"lastname":"Tell",
"zipcode":"15487"
}
]
},
{
"_id":"blood_1",
"type":"AB",
"list":[
{
"firstname":"Mary",
"lastname":"Smith",
"zipcode":"12345"
},
{
"firstname":"John",
"lastname":"Henry",
"zipcode":"54624"
},
{
"firstname":"Jacob",
"lastname":"Tell",
"zipcode":"19283"
},
{
"firstname":"William",
"lastname":"Dirk",
"zipcode":"15999"
}
]
}
]
If I only want to return the objects that contain a contact in the list that meets the criteria of firstname = William, lastname = Tell how would I go about doing that? The queries I am doing are not grouping the criteria, so I would get two results where I actually only should be getting one.
How would I do the same query but also checking for type = AB, as well as the other criteria, which would return no results?
You are looking for the $elemMatch operator. It restricts the query operators to a single element within the array of values.
In the shell your query will look like:
db.people.find( { list : { $elemMatch : { lastName:"Smith", firstName: "John" } } } )
To add the blood type:
db.people.find( {
type : "AB",
list : { $elemMatch : { lastName:"Smith", firstName: "John" } }
} )
This gets a bit verbose using the Java Driver.
DBObject elemMatch = new BasicDBObject();
elemMatch.put("lastName","Smith");
elemMatch.put("firstName","John");
DBObject query = new BasicDBObject();
query.append( "type", "AB");
query.append( "list", elemMatch);
Pass that query to one of the find() methods on the collection and you should get the documents you are looking for.
Note that the $elemMatch query operator will return the entire document, including all of the elements in the array. There is a similarly named projection operator to limit the array elements returned to only those matched.
HTH - Rob.
First things first. I really think your model is utterly wrong. Nested arrays which potentially grow indefinetly are bad for multiple reasons:
If the document exceeds it's padding when new members are written to this array, the document needs to be migrated within a data file. That is a pretty costly operation and you want to prevent it as much as you can.
BSON documents are limited to 16MB. So per blood type you could only have a limited number of people.
All queries tend to be a bit more complicated, the according code more bloated and hence slower.
So how to do it? Take these documents:
{
_id: ObjectId(),
firstName: "Mary",
lastName: "Smith",
zip: "12345",
bt: "AB"
},
{
_id: ObjectId(),
firstName: "John",
lastName: "Smith",
zip: "12345",
bt: "0"
}
With indices set like
db.people.ensureIndex({lastName:1,firstName:1})
db.people.ensureIndex({bt:1})
on the MongoDB shell, you can get what you want with
db.people.find({ lastName:"Smith", firstName: "John"})
or
db.people.find({ bt: "AB" })
This query for example translates to the following
MongoClient client = new MongoClient("localhost");
DB db = client.getDB("yourDB");
DBCollection coll = db.getCollection("yourCollection");
BasicDBOBject query = new BasicDBObject("bt","AB");
DBCursor cursor = coll.find(query);
try {
while( cursor.hasNext() ) {
System.out.println( cursor.next() );
}
} finally {
cursor.close();
}
You might find the MongoDB introduction for working with a Java driver interesting.

Categories

Resources