Datastructure:
Document:
{
"projects": {
"projectName" : String,
"employees": [String]
}
}
Now i want to find a document which has a project with name "project1" and an employee "employee1".
When i try to query by only one property from the nested projects object, it seems to be no problem.
But as soon as i want also to access the nested array. Queries start to fail.
db.documents.find({'projects': { $elemMatch: { name: "project1", $elemMatch: { employees: 'employee1' } } })
I work with meteor collections, so it looks like this:
Documents.findOne({'projects': { $elemMatch: { name: "project1", $elemMatch: { employees: 'employee1' } } })
I also tried this simple approach:
db.collection.find({
"projects.projectName": "project1",
"projects.employees": "employee1"
})
but it didn't work.
EDIT: As J.F. suggested. This Query is correct. But i had a Schema Error. After correcting it, everything worked fine.
You can use the $in operator
https://docs.mongodb.com/manual/reference/operator/query/in/
db.collection.find({
"projects.projectName": "project1",
"projects.employees": {$in: ["employee1"]}
})
Related
I have a small, yet important issue with my code that uses Mongoose/MongoDB. I can't seem to be able to use $pull or $pullAll in Model.findOneAndUpdate({}).
My code is the following:
db?.updateOne({ $pull: {
AutoRole: {
Roles: [value],
}
}
});
And this is my Model schema:
const guildSchema = new mongoose.Schema({
GuildID: String,
AuditChannel: String,
AutoRole: {
Roles: Array
},
});
So far I'm out of ideas on how to make it work. I was wondering if I was doing it wrong, but I can't seem to find what I'm doing exactly wrong.
I think the correct syntax here is:
{
$pull: {
"AutoRole.Roles": value
}
}
I want to only run a statement only if the object is not null. If it is null I want to not do anything. I want to be sure if there is a proper way to achieve this. For example I tried it on MongoDB Playground and it did not work. Here is the link to playground: https://mongoplayground.net/p/yOmRxML88zi
Here is the if-else statement I want to run:
db.collection.aggregate([
{...},
service_type ? { $match: { serviceType: service_type } } : null,
{...},
]);
So if the service_type is not null run the statement else skip to next object in the aggregation. What I want to do in this occasion is get the list of everything in database (objects) that contain certain service type given by the user.
The schema looks something like this:
const sellerSchema = new mongoose.Schema({
user_id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
...,
serviceType: [{ String }],
});
If you're using Mongoose, I suppose you're writing your app using Javascript or TypeScript.
What prevent you, then, from building your query like this?
const aggregatePipeline = [];
if (service_type) aggregatePipeline.push({ $match: { serviceType: service_type }});
...
db.collection.aggregate(aggregatePipeline).exec()
I have a MongoDB collection of documents, using a schema like this:
var schema = new Schema({
name: String,
images: [{
uri: string,
active: Boolean
}]
});
I'd like to get all documents (or filter using some criteria), but retrieve - in the images array - only the items with a specific property (in my case, it's {active: true}).
This is what I do now:
db.people.find( { 'images.active': true } )
But this retrieves only documents with at least one image which is active, which is not what I need.
I know of course I can filter in code after the find is returned, but I do not like wasting memory.
Is there a way I can filter array items in a document using mongoose?
Here is the aggregation you're looking for:
db.collection.aggregate([
{
$match: {}
},
{
$project: {
name: true,
images: {
$filter: {
input: "$images",
as: "images",
cond: {
$eq: [
"$$images.active",
true
]
}
}
}
}
}
])
https://mongoplayground.net/p/t_VxjfiBBMK
I'm currently using AngularJS, and the backend is using NodeJS and Express. I use Mongoose to access the database. I'm trying to figure how to add attributes to nested objects and I can't for the life of me find out how to do it anywhere on the web.
My Schema looks like this:
{
id: {
type: String
},
involved: {
type: String
},
lastMsgRead: Object
}
lastMsgRead will look something like this:
{
user1: "somestringblahblah",
user2: "someotherstring",
}
and so on.
My question is, how would I update lastMsgRead with Mongoose to add another attribute to it, such as adding user3 so it now looks like:
{
user1: "somestringblahblah",
user2: "someotherstring",
user3: "anotherstring"
}
The entire document would like this after the update:
{
id: "string",
involved: "string",
lastMsgRead: {
user1: "somestringblahblah",
user2: "someotherstring",
user3: "anotherstring"
}
}
Edit:
After I add the attribute, how would I then update it in the future?
You can use .dot notation to update in nested object
db.collection.update(
{ },
{ "$set": { "lastMsgRead.user3": "anotherstring" } }
)
in mongoose 5.1.0 and up you can approach this with the MongooseMap.
You can define it in the schema as followed:
{
id: {
type: String
},
involved: {
type: String
},
lastMsgRead: {
type: Map,
of: String
}
}
you can then add a new value by .set(key, value)
myDoc.lastMsgRead.set(key, value)
and get a value by .get(key)
myDoc.lastMsgRead.get(key)
If i have a mongodb collection named Posts with document like following:
{
_id: 11111,
time:40
}
how can i add numeric value to the value 'time' on the fly using .update method?
resulting with the following:
{
_id: 11111,
time:50
}
I was hoping something like:
Posts.update(this._id, {
$set: {time:{time+10}}
});
which don't seem to work. Is this even possible? any ideas?
See $inc
Posts.update({
_id: this._id
}, {
$inc: {
time: 10
}
});