update subdocument in MongoDB works in shell but not in Meteor application - mongodb

I have a collection like this
{
_id: "qex6zPLgigq4KGpFP",
active: true,
name: "event name",
questions: [{
_id: "cff4cc7f1ae67282f1ea142b",
createdBy: "izRFAkhxgemihkRMF",
likes: 2
}, {
_id: "2cf23241ca456703f50a9ce4",
createdBy: "izRFAkhxgemihkRMF",
likes: 0
}]
}
and I initialize my collection in my Meteor application like this:
Events = new Mongo.Collection("events");
Now I want to remove a subdocument from the 'questions' array and it works in the shell with
db.events.update({_id:"qex6zPLgigq4KGpFP"}, {$pull: {'questions': {_id:"cff4cc7f1ae67282f1ea142b"}}})
but NOT in Meteor by calling
Events.update({_id:"qex6zPLgigq4KGpFP"}, {$pull: {'questions': {_id:"cff4cc7f1ae67282f1ea142b"}}})
The return value is always '1', but the document is still there.
It's confusing. Any ideas?

Related

mongo shell query not working for nested documents

I am new to MongoDB and I need help with one basic operation that I am trying. Below is how my mongo collection is structured,
{
id: "<some_id>",
field1: ["value1", "value2", "value3"],
field2:[
field-a {
id: <some_id>,
field-a-1: <some_string>,
field-a-2: [<some_value>, <some_value>]
},
field-b {
id: <some_id>,
field-b-1: <some_string>,
field-b-2: [<some_value>, <some_value>]
},
field-c {
id: <some_id>,
field-c-1: <some_string>,
field-c-2: [<some_value>, <some_value>]
},
field-d {
id: <some_id>,
field-d-1: <some_string>,
field-d-2: [<some_value>, <some_value>]
},
]
}
I want to get the document from “field2" which has id === <requested_id>
I am trying it via mongo shell and below is the query that I am using.
db.posts.find({'field2.id': {$eq:'<some_id>'}})
It is not working. It returns all the documents of the field2 array and I don’t want that.

Use GraphQL Query to get results form MongoDB after aggregation with mongoose

so i have following problem.
I have a mongoDB collection and a corresponding mongoose model which looks like this.
export const ListItemSchema = new Schema<ListItemSchema>({
title: { type: String, required: true },
parentId: { type: Schema.Types.ObjectId, required: false },
});
export const TestSchema = new Schema<Test>(
{
title: { type: String, required: true },
list: { type: [ListItemSchema], required: false },
}
);
As you can see, my TestSchema holds an Array of ListItems inside -> TestSchema is also my Collection in MongoDB.
Now i want to query only my ListItems from a Test with a specific ID.
Well that was not that big of a problem at least from the MongoDB side.
I use MongoDB Aggregation Framework for this and call my aggregation inside a custom Resolver.
Here is the code to get an array of only my listItems from a specific TestModel
const test = TestModel.aggregate([
{$match: {_id: id}},
{$unwind: "$list"},
{
$match: {
"list.parentId": {$eq: null},
},
},
{$replaceRoot: {newRoot: "$list"}},
]);
This is the result
[ { _id: randomId,
title: 't',
parentId: null },
{ _id: randomId,
title: 'x'
parentId: null
} ]
The Query to trigger the resolver looks like this and is placed inside my Test Type Composer.
query getList {
test(testId:"2f334575196fe042ea83afbf", parentId: null) {
title
}
}
So far so good... BUT! Ofc my query will fail or will result in a not so good result^^ because GraphQL expects data based on the Test-Model but receives a completely random array.
So after a lot of typing here is the question:
How do i have to change my query to receive the list array?
Do i have to adjust the query or is it something with mongoose?
i really stuck at this point so any help would be awesome!
Thanks in advance :)
I'm not sure if I understood your issue correctly.
In your graphql, try to leave out exclamation mark(!) from the Query type.
something like :
type Query {
test: TestModel
}
instead of
type Query {
test: TestModel!
}
then you'll get the error message in console but still be able to receive any form of data.

mongo: update subdocument's array

I have the following schema:
{
_id: objectID('593f8c591aa95154cfebe612'),
name: 'test'
businesses: [
{
_id: objectID('5967bd5f1aa9515fd9cdc87f'),
likes: [objectID('595796811aa9514c862033a1'), objectID('593f8c591ba95154cfebe790')]
}
{
_id: objectID('59579ff91aa9514f600cbba6'),
likes: [objectID('693f8c554aa95154cfebe146'), objectID('193f8c591ba95154cfeber790')]
}
]
}
I need to update "businesses.likes" where businesses._id equal to a center value and where businesses.likes contains certain objectID.
If the objectID exists in the array, I want to remove it.
This is what I have tried and didn't work correctly, because $in is searching in all the subdocuments, instead of the only subdocument where businesses._id = with my value:
db.col.update(
{ businesses._id: objectID('5967bd5f1aa9515fd9cdc87f'), 'businesses.likes': {$in: [objectID('193f8c591ba95154cfeber790')]}},
{$pull: {'businesses.$.likes': objectID('193f8c591ba95154cfeber790')}}
)
Any ideas how how I can write the query? Keep in mind that businesses.likes from different businesses can have the same objectID's.

fetching documents based on nested subdoc array value

I'm trying to get all documents in a collection based on a subdocument array values. This is my data structure in the collection i'm seeking:
{
_id: ObjectId('...'),
name: "my event",
members:
[
{
_id: ObjectId('...'),
name: "family",
users: [ObjectId('...'),ObjectId('...'),ObjectId('...')]
},
{
_id: ObjectId('...'),
name: "work",
users: [ObjectId('...'),ObjectId('...'),ObjectId('...')]
}
]
}
I should point out that the schema of these objects are defined like so:
Events:
{
name: { type: String },
members: {type: [{ type: ObjectId, ref: 'MemberGroup' }], default:[] }
}
MemberGroup:
{
name: { type: String },
users: [{type: mongoose.Schema.Types.ObjectId, ref: 'User'}]
}
and of course User is just an arbitrary object with an id.
What i'm trying to fetch: i want to retrieve all events which has a specific user id in its member.users field.
i'm not sure if its event possible in a single call but here is what i've tried:
var userId = new mongoose.Schema.ObjectId('57d9503ef10d5ffc08d6b8cc');
events.find({members: { $elemMatch : { users: { $in: [userId]} } }})
this syntax work but return no elements even though i know there are matching elements (using robomongo to visualize the db)
So after a long search in stackoverflow i came across the good answare here:
MongoDB: How to find out if an array field contains an element?
my query changed to the following which gave me my desired result:
var userId = new mongoose.Schema.ObjectId('57d9503ef10d5ffc08d6b8cc');
events.find({}, {members: { $elemMatch : { users: { $eq: userId} } }})
notice the use of the second find parameter to specify the query limit instead of the first one (which is odd)

MongoDB: Upsert document in array field

Suppose, I have the following database:
{
_id: 1,
name: 'Alice',
courses: [
{
_id: 'DB103',
credits: 6
},
{
_id: 'ML203',
credits: 4
}
]
},
{
_id: 2,
name: 'Bob',
courses: []
}
I now want to 'upsert' the document with the course id 'DB103' in both documents. Although the _id field should remain the same, the credits field value should change (i.e. to 4). In the first document, the respective field should be changed, in the second one, {_id: 'DB103', credits: 4} should be inserted into the courses array.
Is there any possibility in MongoDB to handle both cases?
Sure, I could search with $elemMatch in courses for 'DB103' and if I haven't found it, insert, otherwise update the value. But these are two steps and I would like to do both in just one.