Meteor elemmatch does not match expectations - mongodb

in shell / robomongo
db.mycol.find({_id:"jodi"},{
"progress":{
$elemMatch:{
"status":"todo"
}
}
});
and the
result
this my publish
Meteor.publish('mycol', function() {
if(!this.userId)
return null;
coli = Coli.find({clientId:this.userId});
return coli;
});
and my helper
Coli.find({_id:"jodi"},{
"progress":{
$elemMatch:{
"status":"todo"
}
}
}).fetch()
result from console log(meteor)result
i want show only status todo only
not all
if i running on my console(robomongo) its work
but if i running on my script,all data show (not only status todo)
and this my db
{
"_id" : "jodi",
"clientId" : "BdTw5TtipGkodGLNY",
"project" : "jodi",
"progress" : [
{
"_id" : "ewCzYjeid9G5vpqNy",
"createdAt" : "2016-02-22T12:41:56+07:00",
"status" : "todo",
"title" : "jodi",
"detail" : "jodi"
},
{
"_id" : "ewCzYjeid9G5vpqsNy",
"createdAt" : "2016-02-22T12:41:56+07:00",
"status" : "doing",
"title" : "jodi",
"detail" : "jodi"
}
]
}
i want only show data array in status : todo
in shell it works but in my script status other than todo also appeared

Try this:
Coli.find({_id:"jodi"},
{"progress":{$elemMatch:{"status":"todo"}} },
{fields:{"progress.$": 1}}
).fetch();

thanks everyone
this my fixed code
Coli.find({
"progress":{
$elemMatch:{
"status":"doing"
}
}
})

Related

Mongoose updateMany :: wont find any on given condition

I have updateMany function as follows
Article.updateMany({author: userId}, {author: anonym}, function(err, updated) {
if (err) {
res.send(err);
} else {
res.send(updated);
}
});
userId is = 6068b57dbe4eef0b579120c7
anonym is = 6069870676d6320f39e7e5a2
for testing purposes I have a single article in MongoDB as follows
db.articles.find()
{ "_id" : ObjectId("6068b591be4eef0b579120c8"), "favoritesCount" : 1, "comments" : [ ], "tagList" : [ ], "title" : "Martin", "description" : "Testib", "body" : "Asju", "author" : ObjectId("6068b57dbe4eef0b579120c7"), "slug" : "martin-2hzx78", "createdAt" : ISODate("2021-04-03T18:36:01.977Z"), "updatedAt" : ISODate("2021-04-03T18:53:29.809Z"), "__v" : 0 }
You can see that article has "author" : id field in it which currently shows userId as author.
I want to update that field and transfer authorship to anonym user.
When I send this request to postman I get following response
{
"n": 0,
"nModified": 0,
"ok": 1
}
And database remains unchanged. What am I doing wrong here ?

Add field to every document with existing data (move fields data to new field)

I have almost no experience in SQL or noSQL.
I need to update every document so that my fields "Log*" are under the new field "Log"
I found some help from this StackOverflow, but I am still wondering how to move the data.
Thank you very much
Original document
// collection: Services
{
"_id" : ObjectId("5ccb4f99f4953d4894acbe79"),
"Name" : "WebAPI",
"LogPath" : "Product\\APIService\\",
"LogTypeList" : [
{
"Name" : "ApiComCounter",
"FileName" : "ApiComCounter.log"
},
{
"Name" : "ApiService",
"FileName" : "ApiService.log"
}
]
}
Final Document
// collection: Services
{
"_id" : ObjectId("5ccb6fa2ae8f8a5d7037a5dd"),
"Name" : "InvoicingService",
"Log" : {
"LogPath" : "Product\\APIService\\",
"LogTypeList" : [
{
"Name" : "ApiComCounter",
"FileName" : "ApiComCounter.log"
},
{
"Name" : "ApiService",
"FileName" : "ApiService.log"
}
]
}
}
This requires MongoDB 4.2 or higher:
db.<collection>.updateMany({}, [
{$set: {"Log.LogPath": "$LogPath", "Log.LogTypeList": "$LogTypeList"}},
{$unset: ["LogPath", "LogTypeList"]}
])

Make nested queries in MongoDB 3.0.7

I have sub-events belonging to events belonging to an user, and I know the user's username - how do I get a list of the sub-events?
Is this going in the right direction? Or is it completely off?
db.subevents.find({_id: {$in:
db.events.find({_id: {$in:
db.users.find({"username":"userx"},{_id:1})}},{_id:1})}})
Edit: Here is a sample of the data structure:
/* Event */
{
"_id" : "XjhAqqNBkezKY3mdN",
"name" : "My event",
"userId" : "FiKsAAAgBb7cNoPH7"
}
/* Subevent */
{
"_id" : "WkYAqBXNpJryp7rum",
"name" : "The subevent",
"eventId" : "hQXNzX3jbWppbAYFH"
}
/* User */
{
"_id" : "RTHh5srhLMQp625zF",
"username" : "userx"
}
Following profesor79's advice to use three different calls, I put together this solution to get all the sub-events belonging to the user:
var userIds = db.users.find({"username":"userx"}).map(function(user) {
return user._id;
});
var eventIds= db.events.find({userId: {$in:userIds}}).map(function(event) {
return event._id;
});
db.subevents.find({eventId:{$in:eventIds}});
The only way is to make 3 ddifrent calls in mongo 3.0.7
GetUSerData
GetEventData
GetSubEventData
As you have relational schema here - this should be easy.
You could improve schema and remove subEvent collection by embedding subEvents documents into one events document
EDIT
/* Event */
{
"_id" : "XjhAqqNBkezKY3mdN",
"name" : "My event",
"userId" : "FiKsAAAgBb7cNoPH7"
"subewents" : [{
"_id" : "WkYAqBXNpJryp7rum",
"name" : "The subevent",
"eventId" : "hQXNzX3jbWppbAYFH"
}, {
"_id" : "WkYAqBXNpJryp7rum2",
"name" : "The subevent2",
"eventId" : "hQXNzX3jbWppbAYFH"
}, {
"_id" : "WkYAqBXNpJryp7rum",
"name" : "The subevent",
"eventId" : "hQXNzX3jbWppbAYFH"
}
]
}
/* User */
{
"_id" : "RTHh5srhLMQp625zF",
"username" : "userx"
}

meteor client find is not working due to $eq

I subscribed to my servers's publication as follows:
Template.observedQuestions.onCreated(function(){
var self = this;
self.autorun(function(){
self.subscribe('observedQuestionsFeed');
});
});
Now I need to fetch my data using helper function:
Template.observedQuestions.helpers({
observedQuestionsList : function(){
questions = Questions.find({
observedByUsers : {$exists: true,$elemMatch:{$eq:Meteor.userId()}}});
return questions;
}
});
but it does not work due to $eq being not recognised in minimongo.
How to solve it?
doc sample:
{
"_id" : "rP4JP8jkprwwi3ZCp",
"qUserId" : "NLLW3RBXqnbSGuZ3n",
"type" : "question",
"date" : ISODate("2016-02-13T11:23:10.845Z"),
"subject" : "test",
"question" : "test",
"replies" : [
{
"rID" : "LphcqKnkTHf25SCwq",
"rUserID" : "NLLW3RBXqnbSGuZ3n",
"date" : ISODate("2016-02-13T11:23:10.847Z"),
"answer" : "reply1."
},
{
"rID" : "HxaohnEgxwNJLtf2z",
"rUserID" : "NLLW3RBXqnbSGuZ22",
"date" : ISODate("2016-02-13T11:23:10.848Z"),
"answer" : "reply2"
}
],
"observedByUsers" : [ "Bi24LGozvtihxFrNe" ]
}
Judging from your sample Questions document, the field observedByUsers is a simple array which contains user IDs.
As a result, you could simply use the following query:
Questions.find({observedByUsers: Meteor.userId()});

MongoDB MapReduce producing different results for each document

This is a follow-up from this question, where I tried to solve this problem with the aggregation framework. Unfortunately, I have to wait before being able to update this particular mongodb installation to a version that includes the aggregation framework, so have had to use MapReduce for this fairly simple pivot operation.
I have input data in the format below, with multiple daily dumps:
"_id" : "daily_dump_2013-05-23",
"authors_who_sold_books" : [
{
"id" : "Charles Dickens",
"original_stock" : 253,
"customers" : [
{
"time_bought" : 1368627290,
"customer_id" : 9715923
}
]
},
{
"id" : "JRR Tolkien",
"original_stock" : 24,
"customers" : [
{
"date_bought" : 1368540890,
"customer_id" : 9872345
},
{
"date_bought" : 1368537290,
"customer_id" : 9163893
}
]
}
]
}
I'm after output in the following format, that aggregates across all instances of each (unique) author across all daily dumps:
{
"_id" : "Charles Dickens",
"original_stock" : 253,
"customers" : [
{
"date_bought" : 1368627290,
"customer_id" : 9715923
},
{
"date_bought" : 1368622358,
"customer_id" : 9876234
},
etc...
]
}
I have written this map function...
function map() {
for (var i in this.authors_who_sold_books)
{
author = this.authors_who_sold_books[i];
emit(author.id, {customers: author.customers, original_stock: author.original_stock, num_sold: 1});
}
}
...and this reduce function.
function reduce(key, values) {
sum = 0
for (i in values)
{
sum += values[i].customers.length
}
return {num_sold : sum};
}
However, this gives me the following output:
{
"_id" : "Charles Dickens",
"value" : {
"customers" : [
{
"date_bought" : 1368627290,
"customer_id" : 9715923
},
{
"date_bought" : 1368622358,
"customer_id" : 9876234
},
],
"original_stock" : 253,
"num_sold" : 1
}
}
{ "_id" : "JRR Tolkien", "value" : { "num_sold" : 3 } }
{
"_id" : "JK Rowling",
"value" : {
"customers" : [
{
"date_bought" : 1368627290,
"customer_id" : 9715923
},
{
"date_bought" : 1368622358,
"customer_id" : 9876234
},
],
"original_stock" : 183,
"num_sold" : 1
}
}
{ "_id" : "John Grisham", "value" : { "num_sold" : 2 } }
The even indexed documents have the customers and original_stock listed, but an incorrect sum of num_sold.
The odd indexed documents only have the num_sold listed, but it is the correct number.
Could anyone tell me what it is I'm missing, please?
Your problem is due to the fact that the format of the output of the reduce function should be identical to the format of the map function (see requirements for the reduce function for an explanation).
You need to change the code to something like the following to fix the problem, :
function map() {
for (var i in this.authors_who_sold_books)
{
author = this.authors_who_sold_books[i];
emit(author.id, {customers: author.customers, original_stock: author.original_stock, num_sold: author.customers.length});
}
}
function reduce(key, values) {
var result = {customers:[] , num_sold:0, original_stock: (values.length ? values[0].original_stock : 0)};
for (i in values)
{
result.num_sold += values[i].num_sold;
result.customers = result.customers.concat(values[i].customers);
}
return result;
}
I hope that helps.
Note : the change num_sold: author.customers.length in the map function. I think that's what you want