mongodb java to insert embedded document - mongodb

I have a collection with embedded documents in it.
System
{
System_Info: ...,
Tenant: [
{
Tenant_Id: ...,
Tenant_Info: ...,
Prop_Info: ...
},
{
Tenant_Id: ...,
Tenant_Info: ...,
Prop_Info: ...
} ]
}
If I need to insert another tenant information like this
Tenant { Tenant_Id:2,Tenant_Info:"check",prop_info:"client"}.
whats the mongodb query to insert embedded documents? and how to do it using java?

Use the following code to insert into array :
BasicDBObject query = new BasicDBObject();
query.put( "System_Info", "...." );
BasicDBObject tenant = new BasicDBObject();
tenant.put("Tenant_Id", 2);
tenant.put("Tenant_Info", "check");
tenant.put("Prop_Info", "client");
BasicDBObject update = new BasicDBObject();
update.put("$push", new BasicDBObject("Tenant",tenant));
coll.update(query, update,true,true);

Are you trying to add another Tenant into the array? If so, you would want to create a DBObject representing the Tenant, and then $push it onto the array.
In Java, embedded documents are represented by DBObjects (of which BasicDBObject is a subclass). Here is an example of inserting an embedded document, from the docs:
http://www.mongodb.org/display/DOCS/Java+Tutorial#JavaTutorial-InsertingaDocument
Additionally, here is an example of using $push in Java:
Updating an array in MongoDB using Java driver

...and this is how to do it with mongo-driver version >= 3.1 (mine is 3.2.2):
Document tenant = new Document("Tenant_Id", 2)
.append("Tenant_Info", "check")
.append("Prop_Info", "client");
Bson filter = Filters.eq( "System_Info", "...." ); //get the parent-document
Bson setUpdate = Updates.push("Tenant", tenant);
coll.updateOne(filter, setUpdate);
Hope that helps someone.

Related

MongoDB project nested element in _id field

I'm stuck in something very stupid but I can't get out from my own.
MongoDB v4.2 and I have a collection with documents like this:
{"_id":{"A":"***","B":0}}, "some other fields"...
I'm working on top of mongo-c driver and I want to query only the "_id.B" field but I don't know how I can do it. I have tried:
"projection":{"_id.B":1}: It returns me the whole _id object. _id.A & _id.B.
"projection":{"_id.A":0,"All other fields except _id.B":0}: Returns same as above.
"projection":{"_id.A":0,"_id.B":1}: Returns nothing.
How I can do it to get only some object elements when this object is inside the _id field? The first option works for me with objects that aren't inside the _id field but not here.
Best regards, thanks for your time.
Héctor
You can use MongoDB's $project in aggregation to do this. You can also use $addFields to get _id.B into new field + all other fields in document & finally project _id :0.
Code:
var coll = localDb.GetCollection("yourCollectionName");
var project = new BsonDocument
{
{
"$project",
new BsonDocument
{
{ "_id.B": 1 }
}
}
}
var pipeline = new[] { project };
var result = coll.Aggregate(pipeline);
Test : MongoDB-Playground

Mongo DB Java 3.x Driver - Group By Query

I'd like to learn how to implement group by query using Mongo DB Java 3.x Driver. I want to group my collection through the usernames, and sort the results by the count of results DESC.
Here is the shell query which I want to implement the Java equivalent:
db.stream.aggregate({ $group: {_id: '$username', tweetCount: {$sum: 1} } }, { $sort: {tweetCount: -1} } );
Here is the Java code that I have implemented:
BasicDBObject groupFields = new BasicDBObject("_id", "username");
// count the results and store into countOfResults
groupFields.put("countOfResults", new BasicDBObject("$sum", 1));
BasicDBObject group = new BasicDBObject("$group", groupFields);
// sort the results by countOfResults DESC
BasicDBObject sortFields = new BasicDBObject("countOfResults", -1);
BasicDBObject sort = new BasicDBObject("$sort", sortFields);
List < BasicDBObject > pipeline = new ArrayList < BasicDBObject > ();
pipeline.add(group);
pipeline.add(sort);
AggregateIterable < Document > output = collection.aggregate(pipeline);
The result I need is the count of documents grouped by username. countOfResults returns the total number of the documents the collection has.
You should try not to use old object (BasicDBObject) types with Mongo 3.x. You can try something like this.
import static com.mongodb.client.model.Accumulators.*;
import static com.mongodb.client.model.Aggregates.*;
import static java.util.Arrays.asList;
Bson group = group("$username", sum("tweetCount", 1));
Bson sort = sort(new Document("tweetCount", -1));
AggregateIterable <Document> output = collection.aggregate(asList(group, sort));

mongodb 3.2 java driver aggregation whith match on lookup

I wonder how to perform the aggregation $match on a $lookup collection with the java driver for mongodb 3.2. Here is the structure of the two collections i am working on :
coll_one:{
_id : ObjectId("hex_string"),
foreign_id : ObjectId("hex_string") **the id of coll_two**}
coll_two:{
_id : ObjectId("hex_string"),
actif : true,
closed : false }
The lookup on the two ids (coll_one.foreign_id & coll_two._id) seems to work fine. But when i specify a match on coll_two.actif = true, it returns an empty result.
This is the Java code i'am using :
Bson lookup = new Document("$lookup",
new Document("from", "coll_two" )
.append("localField", "foreign_id")
.append("foreignField", "_id")
.append("as", "look_coll"));
List<Bson> filters = new ArrayList<Bson>();
filters.add(lookup);
//here is the MATCH
filters.add(match(eq("look_coll.actif",true)));
DB().getCollection("coll_one").aggregate(filters);
Evrything works fine whene i remove the match section. I have tried so many combination of possibilities with no success at all !!!
Can any body tells me if this is possible ????
Add your $match request to a Document instance :
Bson match = new Document("$match",
new Document("look_coll.actif", true));
filters.add(match);
Here is a full example :
MongoClient mongoClient = new MongoClient("localhost");
MongoDatabase db = mongoClient.getDatabase("mydb");
Bson lookup = new Document("$lookup",
new Document("from", "coll_two")
.append("localField", "foreign_id")
.append("foreignField", "_id")
.append("as", "look_coll"));
Bson match = new Document("$match",
new Document("look_coll.actif", true));
List<Bson> filters = new ArrayList<>();
filters.add(lookup);
filters.add(match);
AggregateIterable<Document> it = db.getCollection("coll_one").aggregate(filters);
for (Document row : it) {
System.out.println(row.toJson());
}

Generating a new Mongo object id for each document in a collection?

How do you go about creating a unique object id for each document in a mass update?
I've tried,
db.foo.update({ objectId: null }, { $set: { objectId: new ObjectId() }}, { multi: true })
But that gives me the same object id for each document.
Because you're applying a unique value to each doc, you need to iterate over your collection and update the docs one at a time.
In the shell:
db.foo.find({ objectId: null }).forEach(function(doc) {
doc.objectId = new ObjectId();
db.foo.save(doc);
});
You cannot update multiple documents in a single command in MongoDb currently. You can update multiple documents with a common set of changes/updates, but you can not make unique changes to each document. You would need to create a loop to iterate over each document in the shell or your favorite programming language.
You can generate an object Id in MongoDB like this. You can iterate over your doc and use this mongo object id.
const ObjectId = require("mongodb").ObjectID;
const id = new ObjectId
console.log(id)

Using java driver for Mongodb, how do you search for multiple values on the same field?

I'm somewhat new to mongo. I want to query on a field for multiple values.
In SQL, I want something like this:
select * from table where field in ("foo","bar")
Suppose I have the following documents in mongodb
{
"_id":"foo"
}
{
"_id":"bar"
}
I simply want to mimic this query:
db.coll.find( { _id: { $in: [ "foo", "bar" ] } } );
I want to retrieve all documents whose _id is either "foo" or "bar".
And I'd like to do this using the java driver.
I tried something like
BasicDBObject query = new DBObject()
query.append("_id","foo");
query.append("_id","bar");
collection.find(query);
But that seems to return only the "bar" document.
Please help
To use the $in operator, it may be easier to use QueryBuilder to create the query like this:
QueryBuilder qb = new QueryBuilder();
qb.put("_id").in(new String[] {"foo", "bar"});
collection.find(qb.get());
or a little cleaner:
DBObject query = QueryBuilder.start("_id").in(new String[] {"foo", "bar"}).get();
collection.find(query);