how to make mongodb aggregate with $in, $or $and - mongodb

Here is Query in mongodb , where i used to get information on the basis of status, verify_status and their category as well as their Location, their is only one location for the field but need to find in multiple set of location.
Update : I try to run this query in Robo3t , it return blank Result but same query i run in Studio3t it shows expected Result. is there any version issue.
{
"status":{
"$eq":"Active"
},
"verify_status":{
"$eq":"Yes"
},
"$or":[
{
"category":{
"$eq":{
"$oid": "5da0f71e15712b5f7723bb58"
}
}
},
{
"multi_car_status":{
"$eq":"ON"
},
"additional_category":{
"$eq": "5da0f71e15712b5f7723bb58"
}
}
],
"driver_location":{
"$in":[
"5dee787f15712b443f6a5e06",
"5dee787f15712b443f6a5e06"
]
}
}
When i removed the driver_location or "$or" its return resul.there are
result in the db but it return return 0 result. i can't get the result with the both the operators. below is the sample data.
{
"_id" : ObjectId("5ead0f5f15712b5df22d7e23"),
"driver_location" : "5dee787f15712b443f6a5e06",
"category" : ObjectId("5da0f71e15712b5f7723bb58"),
"image" : "7f8e1ddfbe862a7ac4386b2f41fe953f.jpg",
"driver_name" : "Ravi aa",
"email" : "######gmail.com",
"dail_code" : "+1",
"mobile_number" : "83748746",
"dob" : "10/05/2000",
"password" : "######",
"verify_status" : "Yes",
"status" : "Active",
"availability" : "Yes",
"mode" : "Available",
"gender" : "male",
"vehicle_type" : null,
"vehicle_maker" : "5da0f05115712b5fb36e3d02",
"vehicle_model" : "5db22e1215712b25a36b8a3c",
"loc" : {
"lon" : 77.35124777,
"lat" : 28.6543715
},
"address" : {
"address" : "delhi",
"county" : "United States",
"state" : "AR",
"city" : "delhi",
"postal_code" : "122001"
},
"multi_car_status" : "ON",
"additional_category" : [
"5da09ed315712b413333ca58",
"5da0f6fc15712b5c1956eed6",
"5da0f73b15712b5fb36e3d09"
],
}

Related

MOngoDB query to groupby with different fields based on condition to return the latest record

I want to groupby based on condition where my target field can be sender.category or reciever.category based on condition that either of those field belongs to "cat1", and get the last record of each of on sender.id or reciever.id based on createdAt.
Sample Json1:
{
"code" : "34242342",
"name" : "name1",
"amount" : 200,
"sender" : {
"id" : "fsrfsr3242",
"name" : "name2",
"phone" : "12345678",
"category": "cat1"
},
"receiver" : {
"id" : "42342rewr",
"name" : "naem3",
"phone" : "5653679755",
"category": "cat2"
},
"message" : "",
"status" : "done",
"createdAt" : "2019-09-27T09:17:32.597Z"
}
Sample Json2:
{
"code" : "34242342",
"name" : "name1",
"amount" : 200,
"sender" : {
"id" : "fsrfsr3242",
"name" : "name2",
"phone" : "12345678",
"category": "cat3"
},
"receiver" : {
"id" : "42342rewr",
"name" : "naem3",
"phone" : "5653679755",
"category": "cat1"
},
"message" : "",
"status" : "done",
"createdAt" : "2019-09-27T09:17:32.597Z"
}
Query:
[{$match: {
$or: [{ "sender.category": 'cat1' }, {"receiver.category" : 'cat1'}]
}}, {$sort: {
"createdAt": 1
}}, {$group: {
_id: {sender :"$sender.id", reciever : "$receiver.id"},
lastrecord: {
$last: "$$ROOT"
}
}}]
I want to return only the last record, sender.id or receiver.id can have multiple records of which i only want to retrieve the last one. But my query is returning multiple records.
How to get only the last i.e latest one based on above conditions and createdAt?
Sample output:
{
"lastrecord" : {
"name" : "name1",
"amount" : 1000,
"sender" : {
"name" : "name2",
"phone" : "213232141",
"category" : "cat1"
},
"receiver" : {
"name" : "name",
"phone" : "321312412",
"category" : "cat2"
},
"status" : "done",
"createdAt" : "2019-11-25T17:00:17.226+06:30"
}
}
i want this for every sender.id or receiver.id

mongodb find $elemMatch with Multiple Fields

everyone. I need your help. For a script I have to search for users by their ldap id, but I have the problem that I get no output when searching.
a user has the following output.
db.users.find({"name" : "John Sample"} ).toArray()
[
{
"_id" : "testid",
"createdAt" : ISODate("2017-05-11T13:49:35.125Z"),
"services" : {
"password" : {
"bcrypt" : ""
},
"ldap" : {
"id" : "12345678",
"idAttribute" : "uid"
},
"resume" : {
"loginTokens" : [ ]
}
},
"username" : "john",
"emails" : [
{
"address" : "john.sample#test.com",
"verified" : true
}
],
"type" : "user",
"status" : "offline",
"active" : true,
"name" : "John Sample",
"_updatedAt" : ISODate("2018-07-05T18:44:22.061Z"),
"roles" : [
"user"
],
"ldap" : true,
"lastLogin" : ISODate("2018-07-05T10:33:00.712Z"),
"statusConnection" : "offline",
"utcOffset" : 2,
"statusDefault" : "offline"
}
]
I used this command but without success.
db.users.find({"services" : {"$elemMatch": {"ldap" : {"$elemMatch": {"id" : "12345678"}}}}}} ).toArray();
[ ]
$elemMatch is used to find elements that match criteria in an array. But services is an document (sub document), not an array. Just use dot notation to query :
db.users.find({"services.ldap.id":"12345678"})

Fetch Unique Document in Mongodb?

Sample Data:
{"_id" : ObjectId("58bd10e4ff1743c527754160"),
"data" : [
{
"No" : "70",
"Type" : "82",
"Device" : "01",
"timestamp" : "2017-03-06 13:00:32"
}]
},
{"_id" : ObjectId("58bd10sdfe4ff1743csdf0754"),
"data" : [
{
"No" : "75",
"Type" : "22",
"Device" : "02",
"timestamp" : "2017-03-06 13:00:32"
}]
}
I have some document which having same timestamp,so I want to find only unique document on the basis of timestamp.
I have done distinct of timestamp but I want full document.
desired Output:
If same timestamp is there I want only One document.
You will only get one output if you run this query.
db.getCollection('tests').aggregate([{$match:{"data.timestamp":"2017-03-06 13:00:32"}},{$limit:1}])
Solution 1:
db.your_collection.aggregate([
{
$group:{
_id:"$data.timestamp",
data:{
$first:"$data"
}
}
}
])
This will give you following :
{ "_id" : [ "2017-03-06 13:00:32" ], "data" : [ { "No" : "70", "Type" : "82", "Device" : "01", "timestamp" : "2017-03-06 13:00:32" }, { "No" : "10", "Type" : "20", "Device" : "01", "timestamp" : "2018-02-04 10:00:00" } ] }
Solution 2 :
db.your_collection.aggregate([
{ $unwind : '$data'},
{ $group : {
_id : '$data.timestamp',
'No': { $first : '$data.No'},
'Type': { $first : '$data.Type'},
'Device': { $first : '$data.Device'},
'timestamp': { $first : '$data.timestamp'},
}
}
]);
This will give you following :
[
{ "_id" : "2017-03-06 13:00:32", "No" : "70", "Type" : "82", "Device" : "01", "timestamp" : "2017-03-06 13:00:32" },
{ "_id" : "2018-02-04 10:00:00", "No" : "10", "Type" : "20", "Device" : "01", "timestamp" : "2018-02-04 10:00:00" },
]

Aggregation in mongo

Below is a document from my database:
{
"_id" : ObjectId("58635ac32c9592064471cf5b"),
"agency_code" : "v5global",
"client_code" : "whirlpool",
"project_code" : "whirlpool",
"date" : {
"datetime" : 1464739200000.0,
"date" : 1464739200000.0,
"datejs" : ISODate("2016-06-01T00:00:00.000+0000"),
"datetimejs" : ISODate("2016-06-01T00:00:00.000+0000"),
"month" : NumberInt(5),
"year" : NumberInt(2016),
"day" : NumberInt(1)
},
"user" : {
"promoter_id" : NumberInt(19),
"promoter_name" : "Hira Singh Pawar",
"empcode" : "519230"
},
"counter" : {
"store_id" : NumberInt(4),
"store_name" : "Maya Sales ",
"chain_type" : "BS",
"address" : "6 Filamingo Market , Hissar",
"city" : "Hissar",
"state" : "Faridabad",
"region" : "North",
"sap_code" : "N_Far_91103948_1",
"unique_tp_code" : "91103948",
"location" : "6"
},
"insertedon" : {
"date" : 1464739200000.0,
"datejs" : ISODate("2016-06-01T00:00:00.000+0000"),
"datetimejs" : ISODate("2016-06-01T00:00:00.000+0000")
},
"insertedby" : "akshay",
"manager" : {
"manager_id" : NumberInt(5943),
"manager_name" : "Sonu Singh"
},
"type" : "display",
"data" : {
"brand" : "whirlpool",
"sku" : "60",
"model_name" : "Icemagic Fresh",
"sub_cat_name" : "DC",
"cat_name" : "Refrigerator",
"value" : NumberInt(1)
},
"IsDeleted" : false
}
I want to apply aggregation where I have to group it with city, state and region and if that counter has sold refrigerator I need that details in my result e.g if a counter has sold 2 refrigerators of whirlpool company then I want that to reflect in my result.
A counter can also sell other things like washing machines etc. So if they have sold 2 washing machines I want a result with { washingMachine: 2 }.
I have tried everything and nothing seems to be working here:
db.display_mop.aggregate( // Pipeline [
// Stage 1
{ $match: { "project_code":"whirlpool" } },
// Stage 2
{
$group: {
_id: {
"userid": "$user.promoter_id",
"userName": "$user.promoter_name",
"usercode": "$user.empcode",
"storename": "$counter.store_name",
"address": "$counter.address",
"city": "$counter.city",
"state": "$counter.state",
"region": "$counter.region"
}
}
},
],
// Options
{ allowDiskUse: true }

Query to filter the information from a mongodb collection

I have to retrieve a list of users from list of documents which matches the condition. The document structure look like below
{
"_id" : ObjectId("660ff865d4f9075d40a1101c"),
"orderFormId" : "OF-rJw4elBYK",
"orderDetails" : [
{
"courseId" : "53fc31f443fa1fe885d3ad61",
"userInfo" : [
{
"dob" : "2015-03-22T18:30:00.000Z",
"lastName" : "M",
"status" : "Pending Appproval",
"eMail" : "jihin345#baabte.com",
"firstName" : "Arun"
},
{
"status" : "requested",
"firstName" : "asdasd",
"dob" : "2015-03-23T18:30:00.000Z",
"lastName" : "asdafasd",
"userId" : "RQ-11xDPALgR",
"eMail" : "adsasd#baabte.com"
},
{
"status" : "requested",
"firstName" : "asdaf",
"dob" : "2015-03-23T18:30:00.000Z",
"lastName" : "fsdsdf",
"userId" : "RQ-OdoXAOLrB",
"eMail" : "ashdjasufh#baabte.com"
},
{
"status" : "requested",
"firstName" : "asdas",
"dob" : "2015-03-23T18:30:00.000Z",
"lastName" : "asdasd",
"userId" : "RQ-Bw2Xokmda",
"eMail" : "asdasd#gmail.com"
}
],
"userCount" : 5,
"Name" : "Compilers",
"coursePrice" : 1000,
"coursetype" : "offline"
},
{
"courseId" : "53fc31f443fa1fe885d3ad62",
"userInfo" : [
{
"dob" : "2015-03-22T18:30:00.000Z",
"lastName" : "Raj",
"status" : "requested",
"eMail" : "jihin432#baabte.com",
"firstName" : "Nithul"
},
{
"dob" : "2015-03-22T18:30:00.000Z",
"lastName" : "P C",
"status" : "requested",
"eMail" : "jihin345#baabte.com",
"firstName" : "Kahyoom"
}
],
"userCount" : 1,
"Name" : "Computer Science 101",
"coursePrice" : 0,
"coursetype" : "offline"
},
{
"courseId" : "57fc31f443fa1fe885d3ad64",
"userInfo" : [
{
"status" : "requested",
"firstName" : "asdasd",
"dob" : "2015-03-23T18:30:00.000Z",
"lastName" : "aasdasd",
"userId" : "RQ-WqEXBkjv5",
"eMail" : "asdasd#gmail.com"
}
],
"userCount" : 1,
"coursePrice" : 0,
"Name" : "Introduction to Haptics: Self-Paced",
"coursetype" : "offline"
}
],
"companyId" : ObjectId("54128cc57525614f6e3e710a"),
"createdDate" : ISODate("2015-03-23T11:26:29.027Z"),
"updatedDate" : ISODate("2015-03-24T15:00:33.248Z"),
"crmId" : ObjectId("660ab20bd4f9075d40a10d52"),
"urmId" : ObjectId("660ab20bd4f9075d40a10d52"),
"activeFlag" : 0,
"customCompanyCode" : "baa-106",
"status" : "Pending approval"}
From above document i have to get the users who have the status "Approved" in userInfo object which exists inside this document. I have created one query but this will output all the users who have different status.My query look like below,
db.clnTrainingRequest.find({companyId:ObjectId('54128cc57525614f6e3e710a'), "orderDetails.userInfo.status":{$in:['Approved']}}).toArray()
Please any one help me to sort out this issue
You can use aggregation. You need to $unwind orderDetails and the userInfo arrays and then use the $match to get users with status Approved
db.clnTrainingRequest.aggregate(
[ { "$match": { "companyId": ObjectId('54128cc57525614f6e3e710a') },
{ "$unwind": "$orderDetails" },
{ "$unwind": "$orderDetails.userInfo" },
{ "$match": { "orderDetails.userInfo.status": "Approved" }}
]
)