How to get data from a dynamically created Collection in mongoDB - mongodb

we have a collection say TestColl
having document like
{
"_id" : ObjectId("57558a793f50f61400af205c"),
"title" : "Tile 1",
"addSites" : true,
"version" : 11,
"isMajorVersion" : true
},
{
"_id" : ObjectId("654558a793f50f61400af205c"),
"title" : "Title 2,
"addSites" : false,
"version" : 11,
"isMajorVersion" : true
}
for every documemt of TestColl there is a separete collection in DB
so we have another two collections which is created based upon the object Id of TestColl which is
57558a793f50f61400af205c and 654558a793f50f61400af205c
this makes total three collections.
looking for a way to access a collection '57558a793f50f61400af205c' if my query returns document having _id=654558a793f50f61400af205c in a single query.
Constraint : we need only query without creating any stored procedure or function just pure mongodb query

you can use forEach loop and access data from collection like this:
db.kt.find().forEach(function(doc){
var colName = doc._id.str;
var data = db.getCollection(colName).find().toArray();
printjson(data);
print(","); // to have array of arrays [[],[],[]]
})

Related

how to design mongo db model and query with different collection?

I have three collections how can i create a model such that if i want to find a auto_mobile_reference_no of a user with adjustor id: "ABA123" how can i do that?
//Company collection
{
"company_id" : "NUV123",
"company_name" : "ABC",
}
//Adjustor collection
{
"admin" : true,
"claim_adjustor_id" : "ABA123",
"company_id" : "NUV123",
"adjustor_username" : "test",
"adjustor_password" : "test"
},
{
"admin" : true,
"claim_adjustor_id" : "XYQ324",
"company_id" : "NUV123",
"adjustor_username" : "test1",
"adjustor_password" : "test22"
}
//Image collection
{
"claim_adjustor_id" : "ABA123",
"automobile_reference_no" : "1LNHM83W13Y609413",
"date_last_predicted" : "03/12/2019"
}
MongoDB is not designed to do efficient joins across collections. You should look at merging your data (based on access pattern) into a single collections.
If your collections are unsharded, you can however you aggregation framework. You can use combination of $match and $lookup stages to query a foreign collection and join the data with the other. As of version 4.0, $lookup doesn't support sharded collections. So it might not work for you if your dataset is huge.
You can read more here

Mongo db query where condition for a column (list of values) having a value

I am trying to find a way to filter the records in Mongo db using Spring query.
Here is the scenario, let's see I have an Activity entity/document. One of the fields is a list of names. I want to see if I can get all the records that the names field includes get given value, let's say "Joker".
For example, my json in Mongo is
Activity 1 -
{
"_id" : ObjectId("52c14eb92f7ceb854e445354"),
...
"names" : [{
"username" : "username1",
"realname" : "Super Man"
}, {
"username" : "username2",
"realname" : "Iron Man"
}]
}
Activity 2 -
{
"_id" : ObjectId("52c14eb92f7ceb854e445355"),
...
"names" : [{
"username" : "username3",
"realname" : "Bat Man"
}, {
"username" : "username4",
"realname" : "Joker"
}]
}
And I expect the query will let me get Activity 2 only.
Also, if possible, I prefer to use spring Mongo query in my code. Thanks in advance.
Try
db.collection.find({"names.realname": "Joker"});
I never used Spring query but should be something like
Query query = new Query();
query.addCriteria(Criteria.where("names.realname").is("Joker"));
List<MyClass> users = mongoTemplate.find(query, MyClass.class);

Zipping two collections in mongoDB

Not a question about joins in mongoDB
I have two collections in mongoDB, which do not have a common field and which I would like to apply a zip function to (like in Python, Haskell). Both collections have the same number of documents.
For example:
Let's say one collection (Users) is for users, and the other (Codes) is of unique randomly generated codes.
Collection Users:
{ "_id" : ObjectId(""), "userId" : "123"}
{ "_id" : ObjectId(""), "userId" : "456"}
Collection Codes:
{ "_id" : ObjectId(""), "code" : "randomCode1"}
{ "_id" : ObjectId(""), "code" : "randomCode2"}
The desired output would to assign a user to a unique code. As follows:
Output
{ "_id" : ObjectId(""), "code" : "randomCode1", "userId" : "123"}
{ "_id" : ObjectId(""), "code" : "randomCode2", "userId" : "456"}
Is there any way of doing this with the aggregation pipeline?
Or perhaps with map reduce? Don't think so because it only works on one collection.
I've considered inserting another random id into both collections for each document pair, and then using $lookup with this new id, but this seems like an overkill. Also the alternative would be to export and use Python, since there aren't so many documents, but again I feel like there should be a better way.
I would do something like this to get the records from collection 1 & 2 and merge the required fields into single object.
You have already confirmed that number of records in collection 1 and 2 are same.
The below code will loop through the cursor and map the required fields into one object. Finally, you can print the object to console or insert into another new collection (commented the insert).
var usersCursor = db.users.find( { } );
var codesCursor = db.codes.find( { } );
while (usersCursor.hasNext() && codesCursor.hasNext()) {
var user = usersCursor.next();
var code = codesCursor.next();
var outputObj = {};
outputObj ["_id"] = new ObjectId();
outputObj ["userId"] = user["userId"];
outputObj ["code"] = code["code"];
printjson( outputObj);
//db.collectionName.insertOne(outputObj);
}
Output:-
{
"_id" : ObjectId("58348512ba41f1f22e600c74"),
"userId" : "123",
"code" : "randomCode1"
}
{
"_id" : ObjectId("58348512ba41f1f22e600c75"),
"userId" : "456",
"code" : "randomCode2"
}
Unlike relational database in MongoDB you doing JOIN stuff at the app level (so it will be easy to horizontal scale the database). You need to do that in the app level.

mongodb mongoengine filter document on nexted EmbeddedDocumentLIst fields

I have a document with a EmbeddedDocumentList inside an other EmbeddedDocumentlist, I need to filter the collections retrieving only the documents that have a specified value for a field inside the inner EmbeddedDocumentList
the reduced version of my models is:
class RecipeIngredient(EmbeddedDocument):
ingredient = ReferenceField(Ingredient, required=True)
quantity = IntField(required=True)
class RecipeLocalData(EmbeddedDocument):
price = FloatField(required=True)
enabled = BooleanField(default=False)
materialAvailable = BooleanField(default=True)
ingredients = EmbeddedDocumentListField(RecipeIngredient)
class Recipe(Document):
localData = EmbeddedDocumentListField(RecipeLocalServerData)
name = StringField(required=True, unique=True)
deleted = BooleanField(default=False)
this is a sample of documents stored in the collectiosn
{
"_id" : ObjectId("55acf8229d5544137f46b2d9"),
"localData" : [
{
"price" : NumberLong("14112312313"),
"enabled" : true,
"rank" : 12,
"materialAvailable" : true,
"ingredients" : [
{
"ingredient" : ObjectId("5591948c9d5544c7bd68502e"),
"quantity" : 1
}
]
}
],
"name" : "p1",
"deleted" : false,
}
directly on mongodb Im able to achieve this result with the query
db.recipe.find({"localData.ingredients.ingredient":ObjectId("5591948c9d5544c7bd68502e")})
using mongoengine I'm try do query in that way:
Recipe.objects.filter(localData__ingredients__ingredient=ingredient)
Recipe.objects.filter(localData__ingredients__ingredient=ingredient.id)
or using raw pymongo query
Recipe.objects(__raw__={"localData.ingredients.ingredient":document.id})
but is not working
there is some other option instead of filtering at application level?

Collection inside the other collection in mongoDB

I have a CSV holding a function data in it.
It has function ID,Name,Description.
and also it has say 50 records.
for all the records the function ID,Name,Description will remain same.
so i want to create a collection say Func( for common details ) and want to create another collection inside that Func collection ( for the records)
That is for all the records function ID,Name,Description will be same.
Can i create a collection inside the other collection?
Would the following document satify your needs?
The ID, Name and Description information is stored at the top level of the document. Then the func_info field can contain an array of sub-documents containing the records for that function.
{
"ID" : "id1",
"Name" : "function1",
"Description" : "function to add numbers",
"func_info" :[
{
"input1" : 20,
"input2" : 30,
"output" : 50
},
{
"input1" : 7,
"input2" : 7,
"output" : 14
}
]
}