How to write a MongoDB lookup query between 2 collections using Java? - java

For example, create an example collection classes with the following document:
db.classes.insert( [
{ _id: 1, title: "Reading is ...", enrollmentlist: [ "giraffe2", "pandabear", "artie" ], days: ["M", "W", "F"] },
{ _id: 2, title: "But Writing ...", enrollmentlist: [ "giraffe1", "artie" ], days: ["T", "F"] }
])
Create another collection members with the following documents:
db.members.insert( [
{ _id: 1, name: "artie", joined: new Date("2016-05-01"), status: "A" },
{ _id: 2, name: "giraffe", joined: new Date("2017-05-01"), status: "D" },
{ _id: 3, name: "giraffe1", joined: new Date("2017-10-01"), status: "A" },
{ _id: 4, name: "panda", joined: new Date("2018-10-11"), status: "A" },
{ _id: 5, name: "pandabear", joined: new Date("2018-12-01"), status: "A" },
{ _id: 6, name: "giraffe2", joined: new Date("2018-12-01"), status: "D" }
])
The following aggregation operation joins documents in the classes collection with the members collection, matching on the members field to the name field:
db.classes.aggregate([
{
$lookup:
{
from: "members",
localField: "enrollmentlist",
foreignField: "name",
as: "enrollee_info"
}
}
])
The operation returns the following:
{
"_id" : 1,
"title" : "Reading is ...",
"enrollmentlist" : [ "giraffe2", "pandabear", "artie" ],
"days" : [ "M", "W", "F" ],
"enrollee_info" : [
{ "_id" : 1, "name" : "artie", "joined" : ISODate("2016-05-01T00:00:00Z"), "status" : "A" },
{ "_id" : 5, "name" : "pandabear", "joined" : ISODate("2018-12-01T00:00:00Z"), "status" : "A" },
{ "_id" : 6, "name" : "giraffe2", "joined" : ISODate("2018-12-01T00:00:00Z"), "status" : "D" }
]
}
{
"_id" : 2,
"title" : "But Writing ...",
"enrollmentlist" : [ "giraffe1", "artie" ],
"days" : [ "T", "F" ],
"enrollee_info" : [
{ "_id" : 1, "name" : "artie", "joined" : ISODate("2016-05-01T00:00:00Z"), "status" : "A" },
{ "_id" : 3, "name" : "giraffe1", "joined" : ISODate("2017-10-01T00:00:00Z"), "status" : "A" }
]
}
How would you write this in Java with MongoDB?

Related

Mongo upsert do not return modified object _id on update

Mongodb 4.2.15
I'm tring to use mongo Updates with Aggregation Pipeline
My request is very big but here it's core structure
db.runCommand({
"update": "collectionName",
"updates": [
{
"q": { ... },
"u": [
{
"$project": { ... },
"$set": { ... },
"$set": { ... },
"$project": { ... }
}
],
"multi": false,
"upsert": true
}
]
});
After the first execute I receive a result with newly created object's _id
{
"n" : 1,
"nModified" : 0,
"upserted" : [
{
"index" : 0,
"_id" : ObjectId("619997f11501d6eb40c6f64a")
}
],
"opTime" : {
"ts" : Timestamp(1637455857, 61),
"t" : NumberLong(5)
},
"electionId" : ObjectId("7fffffff0000000000000005"),
"ok" : 1.0,
"$clusterTime" : {
"clusterTime" : Timestamp(1637455857, 61),
"signature" : {
"hash" : { "$binary" : "hA0tf5DXMqTNmnVXdMVnpnAKCU0=", "$type" : "00" },
"keyId" : NumberLong(7018546168816730116)
}
},
"operationTime" : Timestamp(1637455857, 61)
}
After the second execution of the same request there is no modified object's _id
{
"n" : 1,
"nModified" : 1,
"opTime" : {
"ts" : Timestamp(1637456057, 19),
"t" : NumberLong(5)
},
"electionId" : ObjectId("7fffffff0000000000000005"),
"ok" : 1.0,
"$clusterTime" : {
"clusterTime" : Timestamp(1637456057, 19),
"signature" : {
"hash" : { "$binary" : "U2yCP6nXUrjBN9ZiLanyl0rgxww=", "$type" : "00" },
"keyId" : NumberLong(7018546168816730116)
}
},
"operationTime" : Timestamp(1637456057, 19)
}
The thing is that my filter conditions do not contain _id of the object but I need to return it with response. I see no useful request configurations. Any suggestions is it possible to get _id at response on update case?

Mongo $lookup Query Getting as alias blank

db.ticket.aggregate([
{
$lookup: {
from: "crmorder",
localField: "subOrderId",
foreignField: "currentStatus",
as: "comments"
}
}
])
in the result comments field is getting blank why?
you have one more table in name of crmorder
In ticket table must have - subOrderId field
In crmorder table must have - currentStatus field
and also ticket table subOrderId field == crmorder table currentStatus field
here is the sample snippt:
db.orders.insert([
{ "_id" : 1, "item" : "almonds", "price" : 12, "quantity" : 2 },
{ "_id" : 2, "item" : "pecans", "price" : 20, "quantity" : 1 },
{ "_id" : 3 }
])
db.inventory.insert([
{ "_id" : 1, "sku" : "almonds", description: "product 1", "instock" : 120 },
{ "_id" : 2, "sku" : "bread", description: "product 2", "instock" : 80 },
{ "_id" : 3, "sku" : "cashews", description: "product 3", "instock" : 60 },
{ "_id" : 4, "sku" : "pecans", description: "product 4", "instock" : 70 },
{ "_id" : 5, "sku": null, description: "Incomplete" },
{ "_id" : 6 }
])
db.orders.aggregate([
{
$lookup:
{
from: "inventory",
localField: "item",
foreignField: "sku",
as: "inventory_docs"
}
}
])

How merge many documents into one using MongoDB's Java Driver?

I'm working with documents that contain music playlists.
Each document has this structure:
{
"user_id": "5858",
"playlists": [
{
"name": "My Playlist",
"guild_ids": ["7575"],
"items": [
{
"title": "title",
"url": "url",
"duration": 200000
}
]
}
]
}
I would like to extract all playlists from the same guild.
But the thing is that i'd like the results to be returned in a single document. One single document with a list of playlists.
The expected result for guild_id=5656 would be like this:
{
"playlists": [
{
"name": "My Playlist",
"guild_ids": ["5656"],
"items": [
{
"title": "title",
"url": "url",
"duration": 200000
}
]
},
// other playlists where guild_ids contains "5656"
]
}
I tried to use aggregation but i always get the same number of documents as the number of unique user_ids. I get the playlists grouped by user_id.
The following query can get us the expected output:
db.collection.aggregate([
{
$unwind:"$playlists"
},
{
$match:{
"playlists.guild_ids":{
$in:["7575"]
}
}
},
{
$group:{
"_id":null,
"playlists":{
$push: "$playlists"
}
}
},
{
$project:{
"_id":0
}
}
]).pretty()
Data set:
{
"_id" : ObjectId("5d88225e38db7cf8d3f75cd6"),
"user_id" : "5858",
"playlists" : [
{
"name" : "My Playlist",
"guild_ids" : [
"7575"
],
"items" : [
{
"title" : "title",
"url" : "url",
"duration" : 200000
}
]
}
]
}
{
"_id" : ObjectId("5d88225e38db7cf8d3f75cd7"),
"user_id" : "5858",
"playlists" : [
{
"name" : "My Playlist 2",
"guild_ids" : [
"1234"
],
"items" : [
{
"title" : "title",
"url" : "url",
"duration" : 200000
}
]
}
]
}
{
"_id" : ObjectId("5d88225e38db7cf8d3f75cd8"),
"user_id" : "5858",
"playlists" : [
{
"name" : "My Playlist 3",
"guild_ids" : [
"7575"
],
"items" : [
{
"title" : "title",
"url" : "url",
"duration" : 200000
}
]
}
]
}
Output:
{
"playlists" : [
{
"name" : "My Playlist",
"guild_ids" : [
"7575"
],
"items" : [
{
"title" : "title",
"url" : "url",
"duration" : 200000
}
]
},
{
"name" : "My Playlist 3",
"guild_ids" : [
"7575"
],
"items" : [
{
"title" : "title",
"url" : "url",
"duration" : 200000
}
]
}
]
}
Query analysis: We are unwinding the playlists, filtering only those which has 7575 guild ID and then grouping them all again.

How to update multiple fields(array field and normal field) in a single document of mongo db at a time using JAVA?

I want to update request fields only in an array using java.This is my existing document in mongo db:
{
"_id": "6691e5068dwe335w42cb0a699650f",
"Opportunity_Owner": "Self",
"Account_Name": "IC",
"Lead_Source": "Callbox",
"Opportunity_Name": "name1 ",
"Stage": "Proposal",
"Stage_Status": "A",
"1555570551211": [],
"1555556165153": [],
"1555556059584": [{
"id": "1557389940585",
"Notes": "Note 1"
},
{
"id": "1557389945398",
"Notes": "Hi Bobby "
},
{
"id": "1557389978181",
"Notes": "Spoken to Bobby."
},
{
"id": "1557389990159",
"Notes": "plan to call on 29/Apr"
}
],
"createdBy": "2c18b8dbb7d74a41a66f53a90117480a",
"createdDate": "1562911250917"
}
Request payload:
{
"_id" : "6691e5068dwe335w42cb0a699650f",
"Stage_Status" : "I",
"1555556059584" : [
{
"id" : "1557389940585",
"Notes" : "updated note 123"
}
]
}
I am trying to update "Stage_Status" and "1555556059584.Notes" at a time using $set.I am able to update "Stage_Status" but "1555556059584" array is going to reset with what i have updated with last one.
expected output:
{
"_id" : "6691e5068dwe335w42cb0a699650f",
"Opportunity_Owner" : "Self",
"Account_Name" : "IC",
"Lead_Source" : "Callbox",
"Opportunity_Name" : "name1 ",
"Stage" : "Proposal",
"Stage_Status" : "I",
"1555570551211" : [],
"1555556165153" : [],
"1555556059584" : [
{
"id" : "1557389940585",
"Notes" : "updated note 123"
},
{
"id" : "1557389945398",
"Notes" : "Hi Bobby "
},
{
"id" : "1557389978181",
"Notes" : "Spoken to Bobby."
},
{
"id" : "1557389990159",
"Notes" : "plan to call on 29/Apr"
}
],
"createdBy" : "2c18b8dbb7d74a41a66f53a90117480a",
"createdDate" : "1562911250917"
}
can any one please help me to figure it out in java.
I guess you wanted to update Stage_Status and 1555556059584.Notes at Once .
here is a demo about it
> db.student.find()
{ "_id" : ObjectId("5d2c09ea8ed60ae70d3dd76b"), "name" : "bigbang", "courses" : [ { "name" : "en", "classRoom" : "9001" }, { "name" : "math", "classRoom" : "1001" } ] }
> db.student.update({name:'bigbang','courses.name':'en'},{ $set: {'courses.$.classRoom':'1009',name :"course"} })
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.student.find()
{ "_id" : ObjectId("5d2c09ea8ed60ae70d3dd76b"), "name" : "course", "courses" : [ { "name" : "en", "classRoom" : "1009" }, { "name" : "math", "classRoom" : "1001" } ] }
the java demo is like this
collection.updateOne(and(eq("Stage_Status","A"),eq("1555556059584.id","1557389940585")),new Document("$set" ,new Document("Stage_Status","YOUR_NEW_VALUE").append("1555556059584.$.Notes","YOUR_NEW_VALUE")));
you must set the 1555556059584.id to let the diver know which element to be update .

mongo $near command on Nested Array

{
"merchantId" : "M168976258",
"catalogTypeId" : "catalogTypeProduct",
"items" : [
{
"name" : "Product 1",
"location" : {
"type" : "Point",
"coordinates" : [
0,
0
]
}
},
{
"name" : "Product 2",
"location" : {
"type" : "Point",
"coordinates" : [
0,
0
]
}
},
{
"name" : "Product 3",
"location" : {
"type" : "Point",
"coordinates" : [
0,
0
]
}
}
}
I able to Perfrom mongo near command on document which is having single location
using below command
db.abc.find({
location :{
$near : {
$geometry : {
index : "Point" ,
coordinates : [19.1, 72.89]
},
$maxDistance : 10000
}
}
})
but i'm not able to perform on document which having nested array can anybody help me out to find out problem
By running this query i get following error
db.catalogForAdminAndMerchant.find({
"items.location" :{
$near : {
$geometry : {
index : "Point" ,
coordinates : [19.1, 72.89]
},
$maxDistance : 10000
}
}
})
o/p is
planner returned error: unable to find index for $geoNear query
but have created the index
by running db.catalogForAdminAndMerchant.getIndexes() i get
/* 1 */
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "catalog-db.catalogForAdminAndMerchant"
},
/* 2 */
{
"v" : 1,
"key" : {
"_fts" : "text",
"_ftsx" : 1
},
"name" : "CatalogForAdminAndMerchant_TextIndex",
"ns" : "catalog-db.catalogForAdminAndMerchant",
"weights" : {
"items.name" : 3
},
"default_language" : "english",
"language_override" : "language",
"textIndexVersion" : 3
},
/* 3 */
{
"v" : 2,
"key" : {
"address.items[i].location" : "2dsphere"
},
"name" : "address.items[i].location_2dsphere",
"ns" : "catalog-db.catalogForAdminAndMerchant",
"2dsphereIndexVersion" : 3
}

Categories

Resources