how to count number of sub object (same document) in mongodb [duplicate] - mongodb

This question already has answers here:
Query for documents where array size is greater than 1
(14 answers)
Closed 7 years ago.
Example document:
{
"aliases" : {
"name" : [
"Brinton McKay",
"Dr. Theopolis",
"Galactic Spiral Sound",
"Highrise",
"Memory Boy",
"Semblance Factor",
"Spy (2)",
"Three O'Clock High"]}
}
How i can count the number of "name" under "aliases"?
I would like to print all _id who which contains more than 3 aliases.
any help would be appreciated.

Please check the below query :
db.collection.find({ $where : function()
{ return Object.keys(this.aliases.name).length > 3 } });
OR
db.collection.aggregate([
{$project : { _id :1 , numb : {$size : "$aliases.name"} }
},
{$match : { numb :{$gt : 3 }}
}
]);
PS : you can see the documentation in below link :
http://docs.mongodb.org/manual/reference/operator/query/where/

Related

MongoDb Need help in finding highest value in database using aggregate [duplicate]

This question already has answers here:
how to get the max value of a field in MongoDB
(2 answers)
mongodb how to get max value from collections
(9 answers)
MongoDB find and return all with max value
(1 answer)
Closed 2 years ago.
I am working on a query to find the subject title, subject type, and credit value of subject with highest credit value. This is the query I have come up with:
db.Subject.aggregate([{$match:{"subject.credit":{$max:true}},
{$project:{"subject.subTitle":1, "subject.type":1, "subject.credit":1, _id: 0}}
]).pretty()
This doesn't seem to net anything.
and
db.Subject.aggregate([{$match:{"subject.credit":$max}},
$project:{"subject.subTitle":1, "subject.type":1, "subject.credit":1, _id: 0}}
]).pretty()
This nets and error as shown below:
E QUERY [js] ReferenceError: $max is not defined :
#(shell):1:32
Here is a part of the database that contains the highest credit value:
db.Subject.insert(
{
"_id":ObjectId(),
"subject":{
"subCode":"CSCI321",
"subTitle":"Final Year Project",
"credit":6,
"type":"Core",
"assessments": [
{ "assessNum": 1,
"weight":30,
"assessType":"Presentation",
"description":"Prototype demonstration" },
{ "assignNum": 2,
"weight":70,
"assessType":"Implementation and Presentation",
"description":"Final product Presentation and assessment of product implementation by panel of project supervisors" }
]
}
}
)
A good strategy, if you don't have an index, is to collapse all documents and get one value:
const pipeline = [
{
"$project" : {
"subTitle" : "$subject.subTitle",
"type" : "$subject.type",
"credit" : "$subject.credit",
"_id" : 0
}
},
{
"$sort" : {
"credit" : -1
}
},
{
"$limit" : 1
}
]
db.Subject.aggregate(pipeline)
Query
$project We want only a subset of fields
$sort to get the highest credit first.
$limit:1 to get only the highest.
db.Subject.find({},{"subject.subTitle":1, "subject.type":1, "subject.credit":1,"_id":0}).sort({"subject.credit":-1})
just use this

Simple $match greater than $gt not working [duplicate]

This question already has answers here:
compare two fields of same document [duplicate]
(1 answer)
MongoDb query condition on comparing 2 fields
(4 answers)
Closed 3 years ago.
This is the result of an aggregate query,
{
"_id" : ObjectId("5dab3240dfbe9a15cd69771d"),
"isManual" : false,
"frequency" : 60,
"lastExecuted" : ISODate("2019-10-21T03:38:15.114Z"),
"lastExecutedTimeFromNow" : 129.58105
}
{
"_id" : ObjectId("5dad47c65310a16581cc6294"),
"isManual" : false,
"frequency" : 50,
"lastExecuted" : ISODate("2019-10-25T00:00:00.000Z"),
"lastExecutedTimeFromNow" : 100
}
{
"_id" : ObjectId("5dad48a55310a16581cc6332"),
"isManual" : true,
"frequency" : 100,
"lastExecuted" : ISODate("2019-10-23T00:00:00.000Z"),
"lastExecutedTimeFromNow" : 50
}
I wanted to filter the documents where the field lastExecutedTimeFromNow greater than frequency. But it returns 0 results.
Here's the aggregate query I'm using,
db.getCollection('test').aggregate([
{
$match: {
"lastExecutedTimeFromNow": { $gte: "$frequency" }
}
}
])
Any clue on where I'm going wrong or any help on this would really be great.
You can use $expr but keep in mind it's slower than normal $match
db.getCollection('test').aggregate([
{
$match: {
$expr: {
$gte: [
"$lastExecutedTimeFromNow",
"$frequency"
]
}
}
}
])

Mongo field A greater than field B plus a value [duplicate]

This question already has answers here:
Mongo field A greater than field B
(4 answers)
Closed 5 years ago.
I want to get records of a MongoDB collection that sticks to this condition: fieldA > fieldB + someNaturalValue. This is what I tried so far:
db.getCollection('collection').find({
$where: function() {
return this.fieldA > this.fieldB + 10000}
});
// or
db.getCollection('collection').aggregate([
{ "$project" : {
"sum" : {"$add" : ["$fieldB", 10000]}
}
},
{ "$match" : {
"sum" : {"$lte" : "$fieldA"}
}
}
]);
The issue I face here is the extra value that I need to add in the condition to one of the fields. Those are not working, that value is not taken into account. What I am missing? I appreciate any kind of help.
Sample Data
db.collection.insert({fieldA : 21000, fieldB : 10000}); //1 ok
db.collection.insert({fieldA : 15000, fieldB : 8000}); //2 nok
db.collection.insert({fieldA : 24000, fieldB : 22000}); //3 nok
db.collection.insert({fieldA : 22000, fieldB : 1000}); //4 ok
Adjusted code from the duplicated question:
db.collection.aggregate([
{$project: {
cmp_value: {$cmp: ['$fieldA', {$add: ['$fieldB', 10000]}]},
obj: '$$ROOT'
}},
{$match: {cmp_value: {$gt: 0}}},
{ $replaceRoot: { newRoot: '$obj' } }
])
$where should be avoided where possible. Documentation is quite clear about it:
The $where provides greater flexibility, but requires that the database processes the JavaScript expression or function for each document in the collection

MongoDB query selecting documents with distinct fields [duplicate]

This question already has answers here:
Select Max() with "group by" in mongodb
(4 answers)
Closed 6 years ago.
Imagine I have a MongoDB collection such as the following, where each row corresponds to a document:
{name:'rick', age:30}
{name:'john', age:40}
{name:'rick', age:35}
{name:'john', age:20}
{name:'jeff', age:50}
{name:'jeff', age:40}
Some documents have the "name" field set to the same value (2 ricks, 2 johns and 2 jeffs). If two or more documents have the "name" field set to the same value, of these I want to select only the document with the highest age. Like this:
{name:'rick', age:35}
{name:'john', age:40}
{name:'jeff', age:50}
Is there a rick aged 30 and a rick aged 35? I select rick aged 35! And so on...
But how can the query look like?
db.getCollection('Mytest').aggregate({$group:{_id:{"name":"$name"}, age: { $max: "$age" }}})
Output:
{
"_id" : {
"name" : "jeff"
},
"age" : 50
}
/* 2 */
{
"_id" : {
"name" : "john"
},
"age" : 40
}
/* 3 */
{
"_id" : {
"name" : "rick"
},
"age" : 35
}
db.collection.aggregate([{$group:{_id:"$name",sal:{$max:"$age"}}}]);

Change _id value from a number to ObjectId()? [duplicate]

This question already has answers here:
How to update the _id of one MongoDB Document?
(7 answers)
Closed 8 years ago.
I have a collection (510 documents) where _id are numbers :
{ "_id" : "1",
"name" : "eric" }
{ "_id" : "2",
"name" : "tom" }
....
and I want to change their values to ObjectId() to be like this:
{ "_id" : ObjectId("53849e258bf3be07804a00d0"),
"name" : "eric" }
{ "_id" : ObjectId("53849e388bf3be07804a00d1"),
"name" : "tom" }
....
so I tried:
db.contacts.find().forEach(function(doc) {
db.contacts.update(
{ "_id": doc._id },
{ "$set": { "_id": ObjectId()} }
);
})
but it doesn't work, I got like result:
Mod on _id not allowed
Thank you.
You cannot change the _id of an Object in a collection once it is created (it is not allowed by mongodb at all). However you could copy the full content of the object execpt of the _id and add your new _id with the ObjectId and insert it into your collection. Afterwards you can remove all the Objects where the _id is a number. It's a bit more complicated but the result is the same (and it works).
Have a look here.