Mongoose Sort by elements in array - node.js

i have my docs like this :
[
{
"_id": "1",
"name": "Valerio",
"gender": "M",
"favorites": []
},
{
"_id": "2",
"name": "Samad",
"gender": "M",
"favorites": ["1", "3", "4"]
},
{
"_id": "3",
"name": "Ayub",
"gender": "F",
"favorites": ["1", "4"]
},
{
"_id": "4",
"name": "Apour",
"gender": "M",
"favorites": ["2"]
}
]
and I want to sort them based on _id : "1" exists in the favorites array like this :
[
{
"_id": "2",
"name": "Samad",
"gender": "M",
"favorites": ["1", "3", "4"]
},
{
"_id": "3",
"name": "Ayub",
"gender": "F",
"favorites": ["1", "4"]
},
{
"_id": "4",
"name": "Apour",
"gender": "M",
"favorites": ["2"]
},
{
"_id": "1",
"name": "Valerio",
"gender": "M",
"favorites": []
}
]
here is what I'm using but this is not sorting it's just filtering :
User.find({
$and: [
{ favorites: { $all: [mongoose.Types.ObjectId("1")] } },
{ gender: { $in:['M'] } },
],
})
i would really appreciate any help, thank you in advance.

You can add a temporary key that holds 1 if the key exists
and 0 if the key doesn't exist, sort in descending order based on this temporary key.
db.collection.aggregate([
{
"$addFields": {
"searchElemExists": {
"$cond": {
"if": {
"$in": [
"1", // <-- Value you want to be sorted based on existance
"$favorites"
]
},
"then": 1,
"else": 0
}
}
},
},
{
"$sort": {
"searchElemExists": -1
}
},
{
"$project": {
"searchElemExists": 0,
},
},
])
Playground Execution of Sample Data

Related

How to filter results from collection the $lookup in mongoose

i want to filter the result as the following in mongodb. I use $lookup to populate the result from another collection. Please check my following code
This code below is what i get
{
"_id": "5f3d563122de0730d0f6a754",
"barcode": "1234",
"productname": "Lays Packet",
"brandName": "Lays",
"productSize": "12",
"price": "12",
"quant": "12",
"imageurl": "http://localhost:3000/images/imageurl-1597855281050.jpg",
"remaining": "12",
"creator": "3d943b957fb5db510d824c5cbd6e8f7d",
"__v": 0,
"source": [
{
"_id": "5f3a9bbc325a074240a1a815",
"firstname": "test",
"lastname": "test",
"storename": "test",
"gst": "test",
"phoneNumber": 1,
"email": "1#demo.com",
"address1": "test",
"address2": "test",
"city": "test",
"state": "test",
"country": "test",
"zip": "1",
"password": "1",
"usertype": 3,
"unique_SHOP": "3d943b957fb5db510d824c5cbd6e8f7d",
"__v": 0
}
]
},
How to retrieve only unique_SHOP and zip from source listing.I want result like the one below with one or more fields
{
"_id": "5f3d563122de0730d0f6a754",
"barcode": "1234",
"productname": "Lays Packet",
"brandName": "Lays",
"productSize": "12",
"price": "12",
"quant": "12",
"imageurl": "http://localhost:3000/images/imageurl-1597855281050.jpg",
"remaining": "12",
"creator": "3d943b957fb5db510d824c5cbd6e8f7d",
"__v": 0,
"source": [
{
"zip": "1",
"unique_SHOP": "3d943b957fb5db510d824c5cbd6e8f7d",
}
]
},
The query i use
List.aggregate([
{$match:
{ productname: { $regex: req.params.query,$options: "i" }}
},
{ $lookup:{
from: "suppliers",
localField: "creator",
foreignField: "unique_SHOP",
as: "source"
}
},
])
You can try $lookup with pipeline,
$match condition of creator id
$project to display required fields
{
$lookup: {
from: "suppliers",
as: "source",
let: { creator: "$creator" },
pipeline: [
{
$match: {
$expr: { $eq: ["$$creator", "$_id"] }
}
},
{
$project: {
_id: 0,
zip: 1,
unique_SHOP: 1
}
}
]
}
}
Playground

MongoDB Aggregate with sum of array object values

I have a collection with the following data:
{ "id": 1,
"name": "abc",
"age" : "12"
"quizzes": [
{
"id": "1",
"time": "10"
},
{
"id": "2",
"time": "20"
}
]
},
{ "id": 2,
"name": "efg",
"age" : "20"
"quizzes": [
{
"id": "3",
"time": "11"
},
{
"id": "4",
"time": "25"
}
]
},
...
I would like to perform the MongoDB Aggregation for a sum of quizzes for each document.and set it to totalTimes field
And this is the result that I would like to get after the querying:
{ "id": 1,
"name": "abc",
"age" : "12",
"totalTimes": "30"
"quizzes": [
{
"id": "1",
"time": "10"
},
{
"id": "2",
"time": "20"
}
]
},
{ "id": 2,
"name": "efg",
"age" : "20",
"totalTimes": "36"
"quizzes": [
{
"id": "3",
"time": "11"
},
{
"id": "4",
"time": "25"
}
]
},
...
How can I query to get the sum of quizzes time?
Quite simple using $reduce
db.collection.aggregate([
{
$addFields: {
totalTimes: {
$reduce: {
input: "$quizzes",
initialValue: 0,
in: {
$sum: [
{
$toInt: "$$this.time"
},
"$$value"
]
}
}
}
}
}
])
Mongo Playground

convert to asc order of array data using MongoDB

how to make this data to asc order by user's first name and user's last name.
I got the response, want to sort the records by user's first name but it is taking from creation date I guess when using sort how can I make it base on user's first name and user's last name please guide
{
"response": {
"items": [
{
"_id": "5e71f86bd300b313df52fb2f",
"last_message": {
"text": "Alex",
"users": [
{
"_id": "5e4a8d2d3952132a08ae5764",
"first_name": "zack",
"last_name": "Write"
}
]
},
"texter": [
"alex",
"$0ctg"
],
"title": "New group1",
"group": true,
"members": [
{
"_id": "5e4a8afc3952132a08ae575e",
"first_name": "test3",
"last_name": "test4"
}
],
"managers": [
"5e4a8afc3952132a08ae575e"
],
"member": {
"_id": "5e4a8afc3952132a08ae575e",
"first_name": "test3",
"last_name": "test4"
}
},
{
"_id": "5e4e740f380054797d9db621",
"last_message": {
"text": "",
"users": [
{
"_id": "5e4a8d2d3952132a08ae5764",
"first_name": "yuhan",
"last_name": "jacob"
}
]
},
"texter": [
"",
"",
"",
"",
"",
"new iphone x\n brand new iphone wv wwvqzwzvq had sqswgscq wow you wholeheartedly q \n $600.00",
"helo",
"hello",
"hi"
],
"members": [
{
"_id": "5e4d0973babf2b74ca868f4d",
"first_name": "alex",
"last_name": "hales"
}
],
"managers": [],
"member": {
"_id": "5e4d0973babf2b74ca868f4d",
"first_name": "alex",
"last_name": "hales"
}
}
]
}
}
Tried
{
$sort: {
users: 1,
}
},
doesn't help much
Also if I would like to add two field asc desc order what would be the process in MongoDB
Try this hope this will help you !
{
$sort: { "users.first_name": 1 }
},

nodejs - how to search within last some documents in mongo

Nodejs
dbo.collection("abc")
.find({"name": "Felicity"})
.sort({_id:-1})
.limit()
.exec(
function(err, results){
// my code
}
);
Data in Collection
cansOne = [
{
"_id": ObjectId("5ace23558980..."),
"name": "Khalichi",
"gender": "F",
"type":"Admin"
},
.
.
.
{
"_id": ObjectId("5ace23558980..."),
"name": "Thore",
"gender": "M",
"type":""
},
{
"_id": ObjectId("5ace23558980..."),
"name": "John Snow",
"gender": "M",
"type":"Admin"
},
{
"_id": ObjectId("5ace23558980..."),
"name": "Felicity",
"gender": "F",
"type":"User"
}
]
cansTwo = [
{
"_id": ObjectId("5ace23558980..."),
"name": "Khalichi",
"gender": "F",
"type":"Admin"
},
.
.
.
{
"_id": ObjectId("5ace23558980..."),
"name": "Thore",
"gender": "M",
"type":""
},
{
"_id": ObjectId("5ace23558980..."),
"name": "John Snow",
"gender": "M",
"type":"Admin"
},
{
"_id": ObjectId("5ace23558980..."),
"name": "Felicity",
"gender": "F",
"type":"User"
}
{
"_id": ObjectId("5ace23558980..."),
"name": "Batman",
"gender": "M",a
"type":""
}
]
I have this type of data in collection. there are two type of cases:
1) "type":"" at the end of collection, means it is last document of collection.
2) After "type":"" document, there are some documents in collection.
I want to search one document, but if it is coming after last index of "type":"" document then it will return that doc otherwise it will return null. in short I want to search this record in those amount of data which are comes after last "type":""
Can anyone help.
Thanks in advance.
For example I want to search "name": "Felicity".
Expected output
caseOne = [
{
"_id": ObjectId("5ace23558980..."),
"name": "Felicity",
"gender": "F",
"type":"User"
}
]
caseTwo = []
Are you trying to do this with Mongo query alone, or with your application code? Mongo query alone cannot do this AFAIK, you cannot find a document depends on its relative position to other documents. You need to use application code along with Mongo query, something like:
dbo.collection("abc").find({
$or: [{
name: "Felicity"
}, {
type: ""
}]
})
.sort({
_id: -1
})
.limit()
.exec(
function(err, results) {
// results here contains documents having name: Falicity or type: ""
// do your check here
}
);

How to find duplicate values in mongodb using distinct query?

I am working on Mongodb distinct query, i have one collection with repeated entry, i am doing as per the created_at. But i want to fetch without repeated values.
Sample JSON
{
"posts": [{
"id": "580a2eb915a0161010c2a562",
"name": "\"Ah Me Joy\" Porter",
"created_at": "15-10-2016"
}, {
"id": "580a2eb915a0161010c2a562",
"name": "\"Ah Me Joy\" Porter",
"created_at": "25-10-2016"
}, {
"id": "580a2eb915a0161010c2a562",
"name": "\"Ah Me Joy\" Porter",
"created_at": "01-10-2016"
}, {
"id": "580a2eb915a0161010c2bf572",
"name": "Hello All",
"created_at": "05-10-2016"
}]
}
Mongodb Query
db.getCollection('posts').find({"id" : ObjectId("580a2eb915a0161010c2a562")})
So i want to know about distinct query of mongodb, please kindly go through my post and let me know.
try as follows:
db.getCollection('posts').distinct("id")
It will return all the unique IDs in the collection posts as follows:
["580a2eb915a0161010c2a562", "580a2eb915a0161010c2bf572"]
From MongoDB docs:
The example use the inventory collection that contains the following documents:
{ "_id": 1, "dept": "A", "item": { "sku": "111", "color": "red" }, "sizes": [ "S", "M" ] }
{ "_id": 2, "dept": "A", "item": { "sku": "111", "color": "blue" }, "sizes": [ "M", "L" ] }
{ "_id": 3, "dept": "B", "item": { "sku": "222", "color": "blue" }, "sizes": "S" }
{ "_id": 4, "dept": "A", "item": { "sku": "333", "color": "black" }, "sizes": [ "S" ] }
To Return Distinct Values for a Field (dept):
db.inventory.distinct( "dept" )
The method returns the following array of distinct dept values:
[ "A", "B" ]
Reference:
https://docs.mongodb.com/v3.2/reference/method/db.collection.distinct/
As per my understanding, you want to get distinct results which should eliminates the duplicate id in that collection
By using distinct in mongodb, It will return list of distinct values
db.getCollection('posts').distinct("id");
["580a2eb915a0161010c2a562", "580a2eb915a0161010c2bf572"]
So you should look into mongodb aggregation
db.posts.aggregate(
{ "$group" : { "_id" : "$id", "name" : {"$first" : "$name"}, "created_at" : {"$first" : "$created_at"} }}
)
The output will be list of results which eliminates the duplicate id documents

Resources