mongodb to display only str of objectId - mongodb

collection A document 1
{
"_id" : ObjectId("5c2ee03224acf45a663d8f09"),
"_class" : "document.domain.DDD",
"generated" : false,
"linkIds" : [],
"types" : [],
"metadata" : {
"templateId" : "ABDC",
"userId" : "Master"
}
"versions" : [
{
"revision" : "fb4fb8ec-edfe-4a3e-a1a9-c8c4b2bce678",
"fileId" : "5c2ee03224acf45a663d8f08"
}
]
}
collection B document 1
{
"_id" : ObjectId("5c2ee03224acf45a663d8f08"),
"_class" : "document.domain.RDF",
"extension" : ".pdf",
"rootPath" : "D"
"size" : 152754
}
the field id in collection A , document 1 appears as String in objectid of collection B doc 1.
how to lookup for the string in collection B which appears as objecid?

you have to use mongodb aggregation there
you have view this more on
https://docs.mongodb.com/manual/core/aggregation-pipeline/
and you have to use $lookup operator more you learn this on
https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/
you can achived your task doing this
collectionA.aggregate.([
{
$match:{},// To match and get all doc
},
{
$lookup:
{
from: collection B//<collection to join>,
localField: versions.fileId//<field from the input documents>,
foreignField: _id//<field from the documents of the "from" collection>,
as: versions.file//<output array field>
}
}])

Related

MongoDB Aggregation - How can I" $lookup" a nested document "_id"?

I successfully thanks to the help of the people here managed to $lookup two IDs in my document with their representive document in another collection. The next step I need to take is to further lookup a "nested" ID (refering to a document in another collection).
I tried to simply put another $lookup pipeline up but that just worked part-wise.
So it happens that an "empty" document was included into the chieftain attributes and all other attributes of chieftain where somewhat removed.
See my current aggregate:
db.getCollection('village').aggregate([
{
"$match": { _id: "111" }
},
{
"$lookup": {
from: "character",
localField: "chieftainId",
foreignField: "_id",
as: "chieftain"
}
},
{
"$lookup": {
from: "character",
localField: "villagerIds",
foreignField: "_id",
as: "villagers"
}
},
{
"$lookup": {
from: "bloodline",
localField: "chieftain.bloodline",
foreignField: "_id",
as: "chieftain.bloodline"
}
},
{ "$project" : { "villagerIds" : 0, "chieftainId" : 0}},
{ "$unwind" : "$chieftain" }
])
The result of that is the following:
{
"_id" : "111",
"name" : "MyVillage",
"reputation" : 0,
"chieftain" : {
"bloodline" : []
},
"villagers" : [
{
"_id" : "333",
"name" : "Bortan",
"age" : 21,
"bloodlineId" : "7f02191f-90af-406e-87ff-41d5b4387999",
"villageId" : "foovillage",
"professionId" : "02cbb10a-6c0f-4249-a932-3f40e12d32c5"
},
{
"_id" : "444",
"name" : "Blendi",
"age" : 21,
"bloodlineId" : "b3a8ffeb-27aa-4e2e-a8e6-b382554f326a",
"villageId" : "foovillage",
"professionId" : "45dc9350-c84a-491d-a49a-524834dd5773"
}
]
}
I expected the chieftain part to look like this (this is how the chieftain document looks like without the 'last' $lookup I added):
"chieftain" : {
"_id" : "222",
"name" : "Bolzan",
"age" : 21,
"bloodlineId" : "7c2926f9-2f20-4ccf-846a-c9966970fa9b", // this should be resolved/lookedup
"villageId" : "foovillage",
},
At the point of the lookup, chieftan is an array, so setting the chieftan.bloodline replaces the array with an object containing only the bloodline field.
Move the { "$unwind" : "$chieftain" } stage to before the bloodline lookup stage so the lookup is dealing with an object.

Convert string to objectId in MongoDB 3.4

I need to convert string to objectId in mongoDB, in mongodb 4 it can be achieved through $toObjectId": "$bar_id
But the problem is my mongodb version is 3.4
Is there any way to achieve that in version 3.4?
Upgrading isn't an option since it's used in production env
The use case is I need to do lookup from one collection to another, the collection looks like
Collection F:
{
"_id" : ObjectId("a"),
"field" : "some-field",
"cityId" : "cityId",
"regionId" : "regionId",
"countryId" : "countryId",
}
and collection country looks like (region and city is similar)
{
"_id" : ObjectId("countryId"),
"name": "someName"
}
I tried using query:
db.F.aggregate([
{
$lookup:
{
from: "country",
localField: "countryId",
foreignField: "_id",
as: "country"
}
}
])
but the result looks like:
{
"_id" : ObjectId("a"),
"field" : "some-field",
"cityId" : "cityId",
"regionId" : "regionId",
"countryId" : "countryId",
"country" : [
]
}
Any advice?
Thank you

How to use join in finding data in MongoDB database?

how to join schema in mongodb?
Example :
a collection
{
ObjectId : ObjectId("ABCDE")
userName : "Jason",
level : 30,
money : 200
}
b collection
{
Id : ObjectId("AAACC"),
userId : ObjectId("ABCDE"),
item : "sword"
}
b.aggregate....
i want result is
id : ObjectId("AAACC"), userName : "Jason", item : "sword"
You should use the aggregation pipeline to join two collections and select the required data. I assume here that you have proper identity fields named _id instead of ObjectId and Id as in your sample:
db.items.aggregate([
{
$lookup:
{
from: "users",
localField: "userId",
foreignField: "_id", // ObjectId in your sample
as: "user"
}
},
{ $unwind: "$user" },
{
$project:
{
"item": 1,
"userName": "$user.userName"
// Id: 1 if you will use your names, because only _id is selected by default
}
}
])
The first step is lookup which joins items and users collections on userId field equals _id field in users collection.
Then you should unwind results, because lookup puts all matched users into user field as an array of user documents.
And last step - project result documents to the desired format.
Now sample. If you have following documents in items collection:
{
"_id" : ObjectId("5c18df3e5d85eb27052a599c"),
"item" : "sword",
"userId" : ObjectId("5c18ded45d85eb27052a5988")
},
{
"_id" : ObjectId("5c18df4f5d85eb27052a599e"),
"item" : "helmet",
"userId" : ObjectId("5c18ded45d85eb27052a5988")
},
{
"_id" : ObjectId("5c18e2da5d85eb27052a59ee"),
"item" : "helmet"
}
And you have two users:
{
"_id" : ObjectId("5c18ded45d85eb27052a5988"),
"userName" : "Jason",
"level" : 30,
"money" : 200
},
{
"_id" : ObjectId("5c18dee35d85eb27052a598a"),
"userName" : "Bob",
"level" : 70,
"money" : 500
}
Then the query above will produce
{
"_id" : ObjectId("5c18df3e5d85eb27052a599c"),
"item" : "sword",
"userName" : "Jason"
},
{
"_id" : ObjectId("5c18df4f5d85eb27052a599e"),
"item" : "helmet",
"userName" : "Jason"
},
{
"_id" : ObjectId("5c18e2da5d85eb27052a59ee"),
"item" : "helmet"
}
NOTE: Usually user names should be unique. Consider to use them as identity for users collection. That will also give you desired result in items collection without any joins.
You can use the lookup aggregation operator to join both collections, and then project only the field from collection a that you are interested in:
db.b.aggregate([
{
$lookup: {
from: "a",
localField: "userId",
foreignField: "ObjectId",
as: "user"
}
},
{
$unwind: "$user"
},
{
$project: {
Id: 1
userName: "$user.userName",
item: 1
}
}
]);
I assume a.ObjectId should in fact be called a._id and b.Id should be b._id? Either way the same principle applies.
EDIT: had forgotten the unwind stage. You need this since your lookup will return the new joined field as an array (albeit with one element), so you need this to get rid of the square brackets.

MongoDB Using aggregate and $lookup to simulate a JOIN of collections in Mongo

So I have collections projects which has field contacts.envCon.$id:
{
"contacts" : {
...
"envCon" : {
"$ref" : "contacts",
"$id" : ObjectId("5807966090c01f4174cb1714") <---- NOTICE!!!
}
...
}
}
On contacts collection Object with id Example12345 looks like this:
{
"_id" : ObjectId("5807966090c01f4174cb1714"),
"name" : "Terracon"
}
So I tried the following $lookup from aggregation framework:
db.getCollection('projects').aggregate([
{
$lookup:{
from: "contacts",
localField: "contacts.envCon.id",
foreignField: "id",
as: "example"
}
}
]);
But it is not doing the JOIN what am I missing? how to do lookups between 2 collections using contacts.envCon.id from projects and _id from contacts.
I'm using meteor just in case.
I'm not sure what is going on with your ObjectId values; I'm not even able to insert a field value of ObjectId("Example12345"). The difference in ObjectID values between the two collections is likely what is causing the $lookup to fail.
The aggregation query you provided works in my environment when I let MongoDB generate the _id ObjectID value in "contacts" and store the same value in the "projects" collection.
$ db.projects.find().pretty()
{
"_id" : ObjectId("580832011b3c40dba2ae6e32"),
"contacts" : {
"envCon" : DBRef("contacts", ObjectId("580831d61b3c40dba2ae6e31"))
}
}
$ db.contacts.find().pretty()
{ "_id" : ObjectId("580831d61b3c40dba2ae6e31"), "name" : "Terracon" }
$ db.getCollection("projects").aggregate([ { "$lookup" : { "from" : "contacts", "localField" : "contacts.envCon.id", "foreignField" : "id", "as" : "example" } } ]).pretty()
{
"_id" : ObjectId("580832011b3c40dba2ae6e32"),
"contacts" : {
"envCon" : DBRef("contacts", ObjectId("580831d61b3c40dba2ae6e31"))
},
"example" : [
{
"_id" : ObjectId("580831d61b3c40dba2ae6e31"),
"name" : "Terracon"
}
]
}

Aggregate query to fetch data which does not have blank("") or null value is not working properly

I have this aggregate query to fetch data which does not have blank("") value or null value in my collection. Here is my query :
MyCollectionA.aggregate([
{$lookup: { "from" : "MyCollectionB","localField" : "MyCollectionAId", "foreignField" : "_id", "as" : "myData"}},
{$match: {"myData": {$nin: [null, "", " "]}}},
{$group: {'_id': '$MyCollectionAId'}}]);
This updated query resolved my problems.
MyCollectionA data:
{
"_id" : "AbqMZXWt4kwFbJM8Y",
"MyCollectionBId" : "DEW7QiEA5wbaFkKkJ",
"MyCollectionAName" : "asdfasdf"
}
{
"_id" : "Ac2CJbz6o4xKQETAZ",
"MyCollectionBId" : "5JjzxkxfBsNXsWcrz",
"MyCollectionAName" : "asdfasdfads."
}
{
"_id" : "AcE2WDqbRG9dv3Lsc",
"MyCollectionBId" : "5678179e20a3d410709ba7f4",
"MyCollectionAName" : "asfasfdasdf"
}
{
"_id" : "AcXsSNc6jmmDyEF54",
"MyCollectionBId" : "2Cy9TpzeqwkTibLy9",
"MyCollectionAName" : "asdfasdfadsr"
}
MyCollectionB data:
{
"_id" : "5JjzxkxfBsNXsWcrz",
"myField" : " "
}
{
"_id" : "5678179e20a3d410709ba7f4",
"myField" : null
}
{
"_id" : "2Cy9TpzeqwkTibLy9",
"myField" : "asdf"
}
But this query gives me output with data which has blank and null value.
Expected result would be :
{
"_id" : "2Cy9TpzeqwkTibLy9",
"MyCollectionBId" : "5JjzxkxfBsNXsWcrz",
"myField" : "asdf"
}
Can anyone have idea about this?
Use localField as a field in your collection from where you are calling $lookup. In this case, the field is 'myCollectionBId'.
Also, after the lookup stage, the matching documents from the foreign collection will be appended as an array to the field which is mentioned in the 'as' field in your $lookup stage. So you cannot directly query on 'myData'. You have to use the '$match' operator on 'myData.0.myField'.
db.MyCollectionA.aggregate([
{$lookup: { "from" : "MyCollectionB", "localField" : "MyCollectionBId", "foreignField" : "_id", "as" : "myData"}},
{$match : { "myData":{$exists:true}, "myData.0.myField": {$nin: [null, "", " "]}}},
{$project: { "MyCollectionBId":1, "myField":"myData.0.myField"}}
]);