get count of multiple values of an array in mongodb - node.js

I want to perform a search in mongodb and nodejs which will return the count of ids that I will provide.
my collection is a log table
{
"_id" : ObjectId("5836d0f7f8462cbc6d0caffc"),
"DeviceId" : "abcd1234",
"AppType" : "web",
"UserId" : "5836cb01f8462cbc6d0caff8",
"ArticleId" : "5836cb01f8462cbc6d0caff8",
"Timestamp" : ISODate("2016-11-24T11:37:27.851Z")
},
{
"_id" : ObjectId("5836dba8a2943528448a3050"),
"DeviceId" : null,
"AppType" : null,
"UserId" : null,
"ArticleId" : 5836e493f2acbd1d34648e78,
"Timestamp" : ISODate("2016-11-24T12:23:04.484Z")
},
{
"_id" : ObjectId("5836e445c3b43429b4810ad4"),
"DeviceId" : null,
"AppType" : null,
"UserId" : null,
"ArticleId" : 5836d0f7f8462cbc6d0caffc,
"Timestamp" : ISODate("2016-11-24T12:59:49.820Z")
},
{
"_id" : ObjectId("5836e493f2acbd1d34648e78"),
"DeviceId" : null,
"AppType" : null,
"UserId" : null,
"ArticleId" : 5836d0f7f8462cbc6d0caffc,
"Timestamp" : ISODate("2016-11-24T13:01:07.030Z")
}
and so on...
my search string will be, search need to be performed on ArticleId
{"5836d0f7f8462cbc6d0caffc",
"5836e493f2acbd1d34648e78",
"5836dba8a2943528448a3050"}
and I want a result set like below
{
"1":{ArticleId:"5836d0f7f8462cbc6d0caffc", count:2},
"2":[ArticleId:"5836e493f2acbd1d34648e78", count:9},
"3":[ArticleId:"5836dba8a2943528448a3050", count:35}
}
Can any one please provide me the query, thanks in advance

I don't know if you realize, but all of your counts will be 1.
That's because every _id in Mongo is unique so if it's there then it's there only once.
Also, the output that you want is invalid:
{ 1:{_id:ObjectId("5836d0f7f8462cbc6d0caffc"), count:2},
2:{ObjectId("5836e493f2acbd1d34648e78"), count:9},
3:{ObjectId("5836dba8a2943528448a3050"), count:35}}
It's not valid JSON, not valid JavaScript, not valid Hjson, not valid JSON5, not valid anything - so you will never be able to get that result no matter what you do. (And also, if you change the expected output, every count will still be 1 so fixing the format is pointless anyway.)

Related

Query an array in MongoDB

I have this collection in MongoDB:
{
"_id" : ObjectId("5df013b10a88910018267a89"),
"StockNo" : "33598",
"Description" : "some description",
"detections" : [
{
"lastDetectedOn" : ISODate("2020-01-29T04:36:41.191+0000"),
"lastDetectedBy" : "comp-t",
"_id" : ObjectId("5e3135f68c9e930017de8aec")
},
{
"lastDetectedOn" : ISODate("2019-12-21T18:12:06.571+0000"),
"lastDetectedBy" : "comp-n",
"_id" : ObjectId("5e3135f68c9e930017de8ae9")
},
{
"lastDetectedOn" : ISODate("2020-01-29T07:36:06.910+0000"),
"lastDetectedBy" : "comp-a",
"_id" : ObjectId("5e3135f68c9e930017de8ae7")
}
],
"createdAt" : ISODate("2019-12-10T21:52:49.788+0000"),
"updatedAt" : ISODate("2020-01-29T07:36:22.950+0000"),
"__v" : NumberInt(0)
}
I want to search by StockNo and get the name of the computer that last detected it (lastDetectedBy) only if lastDetectedOn was in the last 5 minutes with Mongoose in node.js with Express.
I also have this collection:
{
"_id" : ObjectId("5df113b10d35670018267a89"),
"InvoiceNo" : "1",
"InvoiceDate" : ISODate("2020-01-14T02:18:11.196+0000"),
"InvoiceContact : "",
"isActive" : true
},
{
"_id" : ObjectId("5df013c90a88910018267a8a"),
"InvoiceNo" : "2",
"InvoiceDate" : ISODate("2020-01-14T02:18:44.279+0000"),
"InvoiceContact : "Bob Smith",
"isActive" : true
},
{
"_id" : ObjectId("5e3096bb8c9e930017dc6e20"),
"InvoiceNo" : "3",
"InvoiceDate" : ISODate("2020-01-14T02:19:50.155+0000"),
"InvoiceContact : "",
"isActive" : true
}
And I want to update all the documents with empty InvoiceContact which has been issued in the last 30 seconds (or any date range between now and sometime in the past) with isActive equals true to isActive equals false. So for example, the first record has been issued in the last 30 seconds without InvoiceContact and isActive is true so this must be updated but the next two records will remain untouched for different reasons, the second record has InvoiceContact and the third record is out of range.
First Part
var mins5 = new Date(ISODate() - 1000* 60 * 5 )
db.getCollection('user').find({$and:[
{ "StockNo":"33598"},
{"detections.lastDetectedOn" : { $gte : mins5 }}
]})
.map(function(list){
var results = [];
list.detections.forEach(function (detections){
if(detections.lastDetectedOn > mins5){
results.push(detections.lastDetectedBy);
}
})
return results;
});
Second Part could be solved by a similar query using update instead of find.

Mongoose findOne by reference returns null

I have some events in the event collection and some users in the users collection.
I have a mapping of events and users in another collection. The event_id field in that collection is a reference to the event collection(ObjectId). But when I search schema using the following command I get null as a response
db.eventusers.findOne({event_id :'57988cd30e9811750324c080'})
returns null
on the other hand when i search using user field which is not a reference, just a string containing user id, I get the result as follows.
db.eventusers.findOne({user_id :"578cdcdd56eaec041b6caf3e"})
{
"_id" : ObjectId("57988d190e9811750324c081"),
"created_at" : "1469615385595",
"updated_at" : "1469615618502",
"user_id" : "578cdcdd56eaec041b6caf3e",
"event_id" : ObjectId("57988cd30e9811750324c080"),
"deleted" : false,
"invited" : false,
"host" : true,
"status" : -1,
"__v" : 0
}
I have found out the solution. If the field was defined in Mongoose Schema as Schema.Types.ObjectId then in the Query id should be ObjectId rather than String. So instead of query {event_id :'57988cd30e9811750324c080'} it should be {event_id :ObjectId('57988cd30e9811750324c080')}:
db.eventusers.findOne({event_id :ObjectId('57988cd30e9811750324c080')})
{
"_id" : ObjectId("57988d190e9811750324c081"),
"created_at" : "1469615385595",
"updated_at" : "1469615618502",
"user_id" : "578cdcdd56eaec041b6caf3e",
"event_id" : ObjectId("57988cd30e9811750324c080"),
"deleted" : false,
"invited" : false,
"host" : true,
"status" : -1,
"__v" : 0
}

MongoDB - duplicate records in fs.files table or its OKAY ?..GridFS

My question is When I save file to MongoDB via GridFS in the fs.files table I have 2 similar records in it ..but the diference is only in _id and length parameter ..So I don´t know if it is OK or it problem somewhere in my code where I trying to save files ? ..
fs.chunks table got the same problem but there I couldn´t see any equal values ..
I could show you my select from fs.files and fs. chunks
EDIT :
Okay...so now I delete all the documents included in table ..and make new upload with file just ONCE..and look at the output from mongo
and the text mode output from robonongo looks like :
/* 1 */
{
"_id" : ObjectId("57144cdb5235ee50191257be"),
"filename" : "fs.files.jpg",
"contentType" : "image/jpeg",
"length" : 32520,
"chunkSize" : 261120,
"uploadDate" : ISODate("2016-04-18T02:56:27.714Z"),
"aliases" : null,
"metadata" : {
"slovo" : "auto",
"slovnyDruh" : "word"
},
"md5" : "f414e665528d8c6f66381d9fd8ce4abe"
}
/* 2 */
{
"_id" : ObjectId("57144cdb5235ee50191257bf"),
"filename" : "fs.files.jpg",
"contentType" : "image/jpeg",
"length" : 114863,
"chunkSize" : 261120,
"uploadDate" : ISODate("2016-04-18T02:56:27.659Z"),
"aliases" : null,
"metadata" : {
"slovo" : "auto",
"slovnyDruh" : "word"
},
"md5" : "f604c165cce422f3bec79333dc0b3805"
}

Mongo: Group, push and sort

I have a mongodb collection data as per below;I want to group by EmployeedID( i.e 0001) and then sort(by age)
{
"_id" : ObjectId("54d0512191a4da7736e9db43"),
"EmployeeID" : "0001",
"Speciality" : "xxx",
"Code" : "P",
"Age" : 8
}
/* 1 */
{
"_id" : ObjectId("54d0512191a4da7736e9db44"),
"EmployeeID" : "0002",
"Speciality" : "yyyyy",
"Code" : "P",
"Age" : 6
}
/* 2 */
{
"_id" : ObjectId("54d0512191a4da7736e9db45"),
"EmployeeID" : "0001",
"Speciality" : "zzz",
"Code" : "P",
"Age" : 5
}
I know I can group using the following way.
collection.aggregate([
{$match:{"EmployeeId":0001}},
{$group:{"_id":"$EmployeeID",
"speciality":{$push:"$Speciality"},
"Code":{$push:"$Code"},
"Age":{$push:"$Age"}}}
])
But how can I using $sort here? SO my result can be something like below;
[{ "EmployeeID" : "0001",
"speciality" : [ "zzz","xxx"],
"Code" :[ "P","P"],
"Age" : [5,8]
}]
You can sort the document prior to the grouping stage:
collection.aggregate([
{$sort: {_id: -1}},
{$match:{"EmployeeId":0001}},
{$group:{"_id":"$EmployeeID",
"speciality":{$push:"$Speciality"},
"Code":{$push:"$Code"},
"Age":{$push:"$Age"}}}
])
Sorting prior to grouping may exceed mongo's memory when dealing with large collections. Fortunately, you can set allowDiskUse to true to allow mongo to write temporary files.

Querying MongoDB with keyword

I have big collection of tweets stored in MongoDB. Tweets look like this one:
"_id" : ObjectId("4c02c58de500fe1be1000005"),
"contributors" : null,
"text" : "Hello world",
"user" : {
"following" : null,
"followers_count" : 5,
"utc_offset" : null,
"location" : "",
"profile_text_color" : "000000",
"friends_count" : 11,
"profile_link_color" : "0000ff",
"verified" : false,
"protected" : false,
"url" : null,
"contributors_enabled" : false,
"created_at" : "Sun May 30 18:47:06 +0000 2010",
"geo_enabled" : false,
"profile_sidebar_border_color" : "87bc44",
"statuses_count" : 13,
"favourites_count" : 0,
"description" : "",
"notifications" : null,
"profile_background_tile" : false,
"lang" : "en",
"id" : 149978111,
"time_zone" : null,
"profile_sidebar_fill_color" : "e0ff92"
},
"geo" : null,
"coordinates" : null,
"in_reply_to_user_id" : 149183152,
"place" : null,
"created_at" : "Sun May 30 20:07:35 +0000 2010",
"source" : "web",
"in_reply_to_status_id" : {
"floatApprox" : 15061797850
},
"truncated" : false,
"favorited" : false,
"id" : {
"floatApprox" : 15061838001
For example, If I want to find tweets about some topic for example, canon, then How should I write a query which checks the "text" and finds all tweets about "canon"?
MongoDB does not have directly native query support to search within text. There is official documentation showing you how you can achieve a simple approach to full text search:
http://www.mongodb.org/display/DOCS/Full+Text+Search+in+Mongo
It involves splitting the text into words, and storing them in an array, which you index. This lets you match against the contents of an array. How you split them up is your choice. Maybe you just do words, lowercase, and match against a lower case keyword. Or maybe you need autocompletion so you do variations of each word, or phonetics, etc. Thats all stemming.
Its not as robust as a full text search engine, designed to do this, but it works. Depending on the language you are using, some frameworks have search packages. For instance, I use mongodb with django's nonrel project, and there is a search app for that which provides stemming and different tool for searching.

Resources