I need to retrieve information that is in the mongoDB, but I'm not sure how to do it :(
Here's the structure part of my collection that I have:
[{
"points" : 171,
"superPoints" : 2228,
"username" : "ammanda",
"posts" : [{
"comments" : [ { "username" : "jamlabtra", "comment" : "Top" }, ... ],
"likes" : { "users" : ['jamlabtra', 'mrcbrandon','pauljames'], "qtty" : 67 },
"type" : "feedback"
},{
"comments" : [ { "username" : "mrcbrandon", "comment" : "I liked it" }, ... ],
"likes" : {"users" : ['mrcbrandon','pauljames'], "qtty" : 46 },
"type" : "suggestion"
}],
},{
"points" : 23,
"superPoints" : 423,
"username" : "pauljames",
"posts" : [ {
"comments" : [ { "username" : "jamlabtra", "comment" : "Top" }, ... ],
"likes" : { "users" : ['mrcbrandon'], "qtty" : 12 },
"type" : "feedback"
}, {
"comments" : [ { "username" : "jamlabtra", "comment" : "Cool!!" }, ... ],
"likes" : {"users" : ['pauljames'], "qtty" : 3 },
"type" : "suggestion"
}],
}]
I need this result (requesting by username):
{
'username': 'ammanda',
'posts': {
'feedbackTotal': 58,
'suggestionTotal': 6,
},
'likes': {
'total': 3266,
'likers': 32,
'perParticipant': 3,
'perPost': 2.17
},
'comments': {
'total': 123,
'commenters': 546,
'perParticipant': 1.3,
'perPost': 3.3
},
'points': {
'total': 32145,
},
}
I've already been able to do some things:
mongodb.collection('evaluation').aggregate([
{ $match: { username: 'ammanda' } },
{
$project: {
_id: 0,
username: 1,
points: 1,
posts: {
$size: '$posts'
},
likes: {
$sum: '$posts.likes.qtty'
},
},
},
])
But I can not get the rest of the information. Could you help me, please?
Related
{
"_id" : ObjectId("5dbdacc28cffef0b94580dbd"),
"owner" : {
"image" : "https://lh3.googleusercontent.com/a-/AAuE7mCpG2jzbEdffPgdeVWnkBKwyzCCwEB1HMbU1LAVAg=s50",
"fullname" : "soeng kanel",
"userID" : "5da85558886aee13e4e7f044"
},
"image" : "soeng kanel-1572711618984.png",
"body" : "sdadadasdsadadas sds",
"date" : ISODate("2019-11-02T16:20:05.558Z"),
"comments" : [
{
"user" : "5da85558886aee13e4e7f044",
"fullname" : "soeng kanel",
"username" : "",
"comment" : "sdsfdsfdsfds",
"_id" : ObjectId("5dbdacc78cffef0b94580dbf"),
"replies" : [
{
"likes" : [
"5da85558886aee13e4e7f044"
],
"date" : ISODate("2019-11-02T16:20:05.558Z"),
"_id" : ObjectId("5dbdacd78cffef0b94580dc0"),
"reply" : "r1111111",
"username" : "",
"fullname" : "soeng kanel",
"user" : "5da85558886aee13e4e7f044"
},
{
"likes" : [],
"date" : ISODate("2019-11-02T16:20:05.558Z"),
"_id" : ObjectId("5dbdacdb8cffef0b94580dc1"),
"reply" : "r222222",
"username" : "",
"fullname" : "soeng kanel",
"user" : "5da85558886aee13e4e7f044"
},
{
"likes" : [],
"date" : ISODate("2019-11-03T03:04:23.528Z"),
"_id" : ObjectId("5dbe4749fa751f05afcc1bd6"),
"reply" : "33333333",
"username" : "",
"fullname" : "soeng kanel",
"user" : "5da85558886aee13e4e7f044"
}
],
"date" : ISODate("2019-11-02T16:20:05.558Z"),
"likes" : []
}
],
"likes" : [
"5da85558886aee13e4e7f044"
],
"project" : {},
"__v" : 2
}
My query is
db.getCollection("posts").aggregate([
{ $match: {_id: ObjectId("5dbdacc28cffef0b94580dbd"), "comments._id": ObjectId("5dbdacc78cffef0b94580dbf") }},
{ $unwind: "$comments"},
{ $match: { "comments._id": ObjectId("5dbdacc78cffef0b94580dbf")}},
{ $project: {"replies": "$comments.replies", _id: 0}},
{ $match: { "replies._id": ObjectId("5dbdacd78cffef0b94580dc0")}},
{ $project: {"likes": "$replies.likes", _id: 0}},
])
With this query I get 3 elements ,
{
"likes" : [
[
"5da85558886aee13e4e7f044"
],
[],
[]
]
}
That is not what I want, what I want is to get by specific
replies by this _id 5dbdacd78cffef0b94580dc0.
And My expectation
{
"likes" : [
[
"5da85558886aee13e4e7f044"
]
]
}
Try using $unwind on replies before you $match stage on replies.
db.collection.aggregate([
{
$match: {
_id: ObjectId("5dbdacc28cffef0b94580dbd"),
"comments._id": ObjectId("5dbdacc78cffef0b94580dbf")
}
},
{
$unwind: {
path: "$comments",
preserveNullAndEmptyArrays: false
}
},
{
$match: {
"comments._id": ObjectId("5dbdacc78cffef0b94580dbf")
}
},
{
$project: {
"replies": "$comments.replies",
_id: 0
}
},
{
$unwind: {
path: "$replies",
preserveNullAndEmptyArrays: false
}
},
{
$match: {
"replies._id": ObjectId("5dbdacd78cffef0b94580dc0")
}
},
{
$project: {
"likes": "$replies.likes"
}
}
])
Above query produce output in the following fashion:
[
{
"likes": [
"5da85558886aee13e4e7f044"
]
}
]
I hope that's okay.
I'm newbie to mongoDB. Here I face with an error while I want to get the maximum value of the difference of two fields.
Here is the structure of data saved in database:
{
"_id" : ObjectId("52b3833bd3e98582d2bfb628"),
"author" : {
"name" : "Graydon Hoare",
"email" : "graydon#gmail.com"
},
"title" : "Why Rust ditched pure functions",
"body" : "sth",
"url" : "http://thread.gmane.org/gmane.comp.lang.rust.devel/3674/focus=3855",
"date" : ISODate("2013-04-30T13:23:00.000Z"),
"starred" : 105,
"ratings" : [
3,
5,
3,
2,
4,
1,
3,
3,
3,
2,
3
],
"comments" : [
{
"user" : "tr0lltherapy",
"upVotes" : 18,
"downVotes" : 2,
"text" : "sth",
"replies" : [
{
"user" : "thedeemon",
"upVotes" : 10,
"downVotes" : 0,
"text" : "sth"
},
{
"user" : "mcandre",
"upVotes" : 0,
"downVotes" : 5,
"text" : "sth"
},
{
"user" : "lacosaes0",
"upVotes" : 30,
"downVotes" : 6,
"text" : "Particular emphasis on memory safety."
}
]
},
{
"user" : "hypster",
"upVotes" : 30,
"downVotes" : 2,
"text" : "tl;dr everybody was type-fu fighting",
"replies" : [
{
"user" : "homoiconic",
"upVotes" : 15,
"downVotes" : 0,
"text" : "Here comes the Big Boss, Hu! Simon Peyton-Jones."
}
]
}
],
"tags" : [
"Rust",
"Computer",
"Programming"
],
"draft" : true,
"published" : true
}
What I want is to get the value of maximum of the subtract of upVotes and downVotes in replies and comments.
db.getCollection('links').aggregate([
{$project: {
_id: "$author",
maxVote: $max: {
$subtract: ["$comments.upVotes", "$comments.downVotes"]
}
}
}
])
I don't know how to fix it!
You can use $map to get the difference for each comment (using $subtract) and then run $max on the output from mapped comments. Additionally you need another nested $max to get the differences from replies, try:
db.col.aggregate([
{
$project: {
maxVote: {
$max: {
$map: {
input: "$comments",
as: "comment",
in: {
$max: {
$concatArrays: [
[ { $subtract: [ "$$comment.upVotes", "$$comment.downVotes" ] } ],
{
$map: {
input: "$$comment.replies",
as: "reply",
in: { $subtract: [ "$$reply.upVotes", "$$reply.downVotes" ] }
}
}
]
}
}
}
}
}
}
}
])
prints:
{ "_id" : ObjectId("..."), "maxVote" : 28 }
I have a collection with multiple documents like
{
"_id" : ObjectId("5a64d076bfd103df081967ae"),
"status" : "",
"Number" : 53,
"values" : [
{
"date" : "2015-05-18",
"value" : 12.41
},
{
"date" : "2015-05-19",
"value" : 12.45
},
],
"Name" : "ABC Banking",
"scheme":"ABC1",
"createdDate" : "21-01-2018"
}
{
"_id" : ObjectId("5a64d076bfd103df081967ae"),
"status" : "",
"Number" : 53,
"values" : [
{
"date" : "2015-05-18",
"value" : 13.41
},
{
"date" : "2015-05-19",
"value" : 13.45
},
],
"Name" : "ABC Banking",
"scheme":"ABC2",
"createdDate" : "21-01-2018"
}
I am Querying collection based on Number field like
db.getCollection('mfhistories').find({'Number':53})
to get all the documents with this Number.
Now I want to group all the collection with Name 'ABC Banking' into an array. so that I will get result based on Name.
so the result should be like
{
"Name":"ABC Banking",
[
{
"_id" : ObjectId("5a64d076bfd103df081967ae"),
"status" : "",
"Number" : 53,
"values" : [
{
"date" : "2015-05-18",
"value" : 13.41
},
{
"date" : "2015-05-19",
"value" : 13.45
},
],
"scheme":"ABC1",
"createdDate" : "21-01-2018"
},
{
"_id" : ObjectId("5a64d076bfd103df081967ae"),
"status" : "",
"Number" : 53,
"values" : [
{
"date" : "2015-05-18",
"value" : 13.41
},
{
"date" : "2015-05-19",
"value" : 13.45
}
],
"scheme":"ABC2",
"createdDate" : "21-01-2018"
}
]
}
Please help..
Thanks,
J
You can use Aggregation Framework for that:
db.col.aggregate([
{
$match: { Number: 53, Name: "ABC Banking" }
},
{
$group: {
_id: "$Name",
docs: { $push: "$$ROOT" }
}
},
{
$project: {
Name: "$_id",
_id: 0,
docs: 1
}
}
])
$$ROOT is a special variable which captures entire document. More here.
db.mfhistories.aggregate(
// Pipeline
[
// Stage 1
{
$match: {
Number: 53
}
},
// Stage 2
{
$group: {
_id: {
Name: '$Name'
},
docObj: {
$addToSet: '$$CURRENT'
}
}
},
// Stage 3
{
$project: {
Name: '$_id.Name',
docObj: 1,
_id: 0
}
}
]
);
I have records in a collection of the following format.
//One parent record
{
"_id" : "someDocID",
"title" : "some title",
"analytics" : [
{
"_id" : "analyticsID1",
"timeSpent" : [
{
"time" : 14,
"pageNo" : 1
},
{
"time" : 4,
"pageNo" : 2
},
{
"time" : 3,
"pageNo" : 1
},
{
"time" : 1,
"pageNo" : 2
}
]
},
{
"_id" : "analyticsID2",
"timeSpent" : [
{
"time" : 12,
"pageNo" : 10
},
{
"time" : 15,
"pageNo" : 11
},
{
"time" : 26,
"pageNo" : 12
},
{
"time" : 13,
"pageNo" : 11
},
{
"time" : 17,
"pageNo" : 10
},
{
"time" : 30,
"pageNo" : 11
}
]
}
]
}
The "pageNo" field contains repeated values. I need to group the pageNo field with adding their respective "time".
This is my required output. ( after "$unwind" operation on analytics )
//Two records after "$unwind" on analytics
{
"_id" : "someDocID",
"title" : "some title",
"analytics" : {
"_id" : "analyticsID1",
"timeSpent" : [
{
"time" : 17, //14+3
"pageNo" : 1
},
{
"time" : 5, //4+1
"pageNo" : 2
}
]
}
}
{
"_id" : "someDocID",
"title" : "some title",
"analytics" : {
"_id" : "analyticsID2",
"timeSpent" : [
{
"time" : 29, //12+17
"pageNo" : 10
},
{
"time" : 58, //15+13+30
"pageNo" : 11
},
{
"time" : 26,
"pageNo" : 12
}
]
}
}
I've tried various combinations of aggregate, group, unwind and project but still can't quite get there and would really appreciate any suggestions.
Here is an aggregate I came up with to provide the output that you mentioned in your comment above. As an FYI, the more elements you have in an array that needs to be unwound, the more memory usage you'll have, and it will take an exponentially amount of time based on array sizes. I would highly recommend you structure your data differently if your arrays are not limited in length.
var aggregrate = [{
$unwind: '$analytics'
}, {
$unwind: '$analytics.timeSpent'
}, {
$group: {
_id: {
analytics_id: '$analytics._id',
pageNo: '$analytics.timeSpent.pageNo'
},
title:{$first:'$title'},
time: {
$sum: '$analytics.timeSpent.time'
},
}
}, {
$group: {
_id: '$_id.analytics_id',
title:{$first:'$title'},
timeSpent: {
$push: {
time: '$time',
pageNo: '$_id.pageNo'
}
}
}
}, ];
This Outputs:
[{
"_id": "analyticsID1",
"title" : "some title",
"timeSpent": [{
"time": NumberInt(17),
"pageNo": NumberInt(1)
}, {
"time": NumberInt(5),
"pageNo": NumberInt(2)
}]
}, {
"_id": "analyticsID2",
"title" : "some title",
"timeSpent": [{
"time": NumberInt(26),
"pageNo": NumberInt(12)
}, {
"time": NumberInt(29),
"pageNo": NumberInt(10)
}, {
"time": NumberInt(58),
"pageNo": NumberInt(11)
}]
}]
I am new to mongodb, I have a dataset that looks like the following, and I'm trying to Write an aggregation query that will determine the number of unique companies with which an individual has been associated.
Schema:
{
"_id" : ObjectId("52cdef7c4bab8bd675297d8b"),
"name" : "AdventNet",
"permalink" : "abc3",
"crunchbase_url" : "http://www.crunchbase.com/company/adventnet",
"homepage_url" : "http://adventnet.com",
"blog_url" : "",
"blog_feed_url" : "",
"twitter_username" : "manageengine",
"category_code" : "enterprise",
"number_of_employees" : 600,
"founded_year" : 1996,
"deadpooled_year" : 2,
"tag_list" : "",
"alias_list" : "Zoho ManageEngine ",
"email_address" : "pr#adventnet.com",
"phone_number" : "925-924-9500",
"description" : "Server Management Software",
"created_at" : ISODate("2007-05-25T19:24:22Z"),
"updated_at" : "Wed Oct 31 18:26:09 UTC 2012",
"overview" : "<p>AdventNet is now Zoho ManageEngine.</p>\n\n<p>Founded in 1996, AdventNet has served a diverse range of enterprise IT, networking and telecom customers.</p>\n\n<p>AdventNet supplies server and network management software.</p>",
"image" : {
"available_sizes" : [
[
[
150,
55
],
"assets/images/resized/0001/9732/19732v1-max-150x150.png"
],
[
[
150,
55
],
"assets/images/resized/0001/9732/19732v1-max-250x250.png"
],
[
[
150,
55
],
"assets/images/resized/0001/9732/19732v1-max-450x450.png"
]
]
},
"products" : [ ],
"relationships" : [
{
"is_past" : true,
"title" : "CEO and Co-Founder",
"person" : {
"first_name" : "Sridhar",
"last_name" : "Vembu",
"permalink" : "sridhar-vembu"
}
},
{
"is_past" : true,
"title" : "VP of Business Dev",
"person" : {
"first_name" : "Neil",
"last_name" : "Butani",
"permalink" : "neil-butani"
}
},
{
"is_past" : true,
"title" : "Usabiliy Engineer",
"person" : {
"first_name" : "Bharath",
"last_name" : "Balasubramanian",
"permalink" : "bharath-balasibramanian"
}
},
{
"is_past" : true,
"title" : "Director of Engineering",
"person" : {
"first_name" : "Rajendran",
"last_name" : "Dandapani",
"permalink" : "rajendran-dandapani"
}
},
{
"is_past" : true,
"title" : "Market Analyst",
"person" : {
"first_name" : "Aravind",
"last_name" : "Natarajan",
"permalink" : "aravind-natarajan"
}
},
{
"is_past" : true,
"title" : "Director of Product Management",
"person" : {
"first_name" : "Hyther",
"last_name" : "Nizam",
"permalink" : "hyther-nizam"
}
},
{
"is_past" : true,
"title" : "Western Regional OEM Sales Manager",
"person" : {
"first_name" : "Ian",
"last_name" : "Wenig",
"permalink" : "ian-wenig"
}
}
],
"competitions" : [ ],
"providerships" : [
{
"title" : "DHFH",
"is_past" : true,
"provider" : {
"name" : "A Small Orange",
"permalink" : "a-small-orange"
}
}
],
"total_money_raised" : "$0",
"funding_rounds" : [ ],
"investments" : [ ],
"acquisition" : null,
"acquisitions" : [ ],
"offices" : [
{
"description" : "Headquarters",
"address1" : "4900 Hopyard Rd.",
"address2" : "Suite 310",
"zip_code" : "94588",
"city" : "Pleasanton",
"state_code" : "CA",
"country_code" : "USA",
"latitude" : 37.692934,
"longitude" : -121.904945
}
],
"milestones" : [ ],
"video_embeds" : [ ],
"screenshots" : [
{
"available_sizes" : [
[
[
150,
94
],
"assets/images/resized/0004/3400/43400v1-max-150x150.png"
],
[
[
250,
156
],
"assets/images/resized/0004/3400/43400v1-max-250x250.png"
],
[
[
450,
282
],
"assets/images/resized/0004/3400/43400v1-max-450x450.png"
]
],
"attribution" : null
}
],
"external_links" : [ ],
"partners" : [ ]
}
Here is the query I tried:
db.companies.aggregate([{
$match: {
"relationships.person": {
$ne: null
}
}
}, {
$project: {
relationships: 1,
_id: 0
}
}, {
$unwind: "$relationships"
}, {
$group: {
_id: "$relationships.person",
count: {
$addToSet: "$relationships"
}
}
}])
I think I now need to get the length of the $relationships array? How would I do that?
When you only want the size of the array you really don't need to unwind...
Just use $size.
Alter your aggregation to:
db.companies.aggregate([{
$match: {
"relationships.person": {
$ne: null
}
}
}, {
$project: {
relationships: 1,
_id: 0,
relationship_size : { $size : "$relationships"}
}
}
}])
This should give you the result you want
From the comment i understand you want some more logic in the aggregation, from outta my head i would alter your aggregation to:
db.companies.aggregate([{
$match: {
"relationships.person": {
$ne: null
}
}
}, {
$project: {
relationships: 1,
_id: 0
}
}, {
$unwind: "$relationships"
}, {
$group: {
_id: "$relationships.person.permalink",
count : {$sum : 1}
}
}])
I can't find a "company name" in your relationships array so i use the permalink property