How to find duplicate values in mongodb using distinct query? - node.js

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

Related

How to update some collection with different query parameters and with different set values?

I have an array of mongoDB collection -
[
{
"_id": "630499244683ed43d56edd06",
"userId": "630499234683ed43d56edd05",
"isPaid": "true"
},
{
"_id": "6304c19bda84477b41b4bbfa",
"userId": "630499234683ed43d56edd05",
"isPaid": "true"
},
{
"_id": "6304c1b5da84477b41b4bbfb",
"userId": "630499234683ed43d56edd05",
"isPaid": "true"
},
{
"_id": "6304c1cbda84477b41b4bbfc",
"userId": "630499234683ed43d56edd05",
"isPaid": "true"
},
]
I just want to add the order property to all the object but for all the specific _id I need to add the different order value
Like this -
[
{
"_id": "630499244683ed43d56edd06",
"userId": "630499234683ed43d56edd05",
"isPaid": "true",
"order": 7
},
{
"_id": "6304c19bda84477b41b4bbfa",
"userId": "630499234683ed43d56edd05",
"isPaid": "true",
"order": 5
},
{
"_id": "6304c1b5da84477b41b4bbfb",
"userId": "630499234683ed43d56edd05",
"isPaid": "true",
"order": 0,
},
{
"_id": "6304c1cbda84477b41b4bbfc",
"userId": "630499234683ed43d56edd05",
"isPaid": "true",
"order": 2
},
]
Please let me know How do I implement this approach in mongoDB?
I'm not using mongoose in my project.
You have to add the structure of the coming data, how it grouped with _id and the count of order. If it is an array of object, you can use loop. I don't think there is a solution to update different values in only one code.
If you want specific ids to have specific order values you need to update them separately. You could use bulkWrite with the updateOne method.
db.collection.bulkWrite( [
{ updateOne: {
filter: { _id: ... },
update: { $set: { order: 1 } }
} },
...
] )
Refer to the MongoDB documentation and to your language driver in particular: https://www.mongodb.com/docs/v6.0/reference/method/db.collection.bulkWrite/#updateone-and-updatemany

Mongoose Sort by elements in array

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

How to get a sorted list of most used values for a field in a mongodb collection

I have some documents resembling the following structure:
{
"name": "item_1",
"category": ["a", "b"]
},
{
"name": "item_2",
"category": ["c"]
},
{
"name": "item_3",
"category": ["a", "c"]
},
{
"name": "item_4",
"category": ["a"]
},
{
"name": "item_5",
"category": ["a"]
}
I'm trying to get a sorted list of the most used values for the category field in all documents within the collection.
So in this example, the return value I'm expecting should be something like this:
[
{
"category": "a",
"count": 4
},
{
"category": "c",
"count": 2
},
{
"category": "b",
"count": 1
}
]
Is there a way to make such a query in mongoose?
Demo - https://mongoplayground.net/p/sBpwwvowXLH
Use aggregation query to $unwind your category into separate documents $group them back by category and get the count
$sum
db.collection.aggregate({
"$unwind": "$category"
},
{
"$group": {
"_id": "$category",
count: { $sum: 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 get distinct value of sub document field with their count in collection in mongodb?

I have a collection with documents like below.I want to get the all distinct value of name of attributes sub-document with their distinct value and count in collection.
Example :
var records = [
{
"attributes": [
{
"name": "color",
"value": "black",
"_id": "5441103a0348ebc91ee75b33"
}
],
"name": "ddd"
},
{
"attributes": [
{
"name": "color",
"value": "red",
"_id": "5441091393450f1619be99af"
},
{
"name": "size",
"value": "L",
"_id": "5441091393450f1619be99b0"
}
],
"name": "one"
},
{
"attributes": [
{
"name": "color",
"value": "black",
"_id": "5441092593450f1619be99b1"
},
{
"name": "size",
"value": "L",
"_id": "5441092593450f1619be99b2"
}
],
"name": "sdfsda"
},
{
"attributes": [
{
"name": "color",
"value": "green",
"_id": "5441093d93450f1619be99b3"
},
{
"name": "size",
"value": "S",
"_id": "5441093d93450f1619be99b4"
}
],
"name": "threee"
},
{
"attributes": [
{
"name": "color",
"value": "green",
"_id": "5441095793450f1619be99b5"
},
{
"name": "size",
"value": "M",
"_id": "5441095793450f1619be99b6"
}
],
"name": "one"
}
]
I want to get output like :
var output =
{
"color" : [
{value : 'red', count : 1}
{value : 'black', count : 2}
{value : 'green', count : 2}
],
"size" : [
{value : 'S', count : 2}
{value : 'L', count : 1}
{value : 'M', count : 1}
]
}
how can i get this output in mongodb?
Can i get this output by aggregate framework of mongodb, if yes, then how? -- high priority
Yes, aggregate can make it.
var output = {};
db.c.aggregate([{
$unwind : "$attributes"
}, {
$group : {
_id : {
name : "$name",
value : "$value"
},
count : {
$sum : 1
}
} // the output after this stage such as
// {_id:{name:"color", value:"green"}, count:2}
// {_id:{name:"size", value:"S"}, count:2}
}, {
$group : {
_id : "$_id.name",
contents : {
$push : {
value : "$_id.value",
count : "$count"
}
}
} // the output after this stage such as
// {_id:"color", contents:[{value:"green", count:2}]}
// {_id:"size", contents:[{value : 'S', count : 2}]}
}]).forEach(function(doc) {
output[doc._id] = doc.contens; // just convert to the format as expected
});

Resources