Mongodb: findOne by ObjectId inside an array of documents - mongodb

Sorry for the confusing title, I'm having a hard time describing it.
Basically, here is the document I have stored in my database:
_id: 5fcf596a27365fb14d938afa
vatid:"BE00000011"
name:"ACME Inc"
users: [ {
_id: 5fcf596a27365fb14d938afb,
id: 5fcf596a27365fb14d938af9,
role:"admin"
}
]
Id like to find the object that contains this id: 5fcf596a27365fb14d938af9 inside the users array.
What would the query look like?
Thanks!

This should do the thing:
{"users.id" : "5fcf596a27365fb14d938af9"}

Related

Push values in Mongo Nested Array

enter image description here
Let's say that we have many documents like this in the photo
I have the above schema. I want to find the document based on _id first and then push an array of values to providedServices which belongs to the _id which is inside barbers array
A little help. Can't seem to find this out!
You need to find the related arrays firstly. For this, you can use $elemMatch or write it as 'barbers._id' : {$elemMatch: parameter}' .
Here we tried to find document with filtering it's own id and barbers id. You can change the filter as you wished. It can be only search on barbers id.
Need to write your DocumentName and your parameters instead of idValue, barbersId, serviceModel.
const result = await DocumentName.findOneAndUpdate(
{
$and:
[
{_id: mongoose.Types.ObjectId(idValue)},
{'barbers': {$elemMatch: {_id: mongoose.Types.ObjectId(barbersId)}}}
]
},
{ $push: { 'barbers.$.providedServices': serviceModel } },
{ new: true })
At first, we found the related barbers array inside of all documents. Then we pushed the model inside of providedServices array into this barbers array.

Create unique indexes for document's objects stored in an array

How do one create unique indexes for document's objects stored in array?
{
_id: 'documentId',
books: [
{
unique_id: 1,
title: 'Asd',
},
{
unique_id: 2,
title: 'Wsad',
}
...
]
}
One thing I can think of is autoincrementing. Or is there any mongo way to do so?
if you remove the _id field from your doc, mongo will automatically add one for you, which is:
guaranteed to be unique
contains the timestamp of creation
lots of other features.
see here: https://docs.mongodb.com/v3.2/reference/method/ObjectId/
Looking at the example object again, are you referring to the ids in the books array?
If so, you can assign them with ObjectIds as well, just like in the document root's _id field:
doc.books.forEach(x => { x.unique_id = new ObjectId() } );

Meteor Collection: find element in array

I have no experience with NoSQL. So, I think, if I just try to ask about the code, my question can be incorrect. Instead, let me explain my problem.
Suppose I have e-store. I have catalogs
Catalogs = new Mongo.Collection('catalogs);
and products in that catalogs
Products = new Mongo.Collection('products');
Then, people add there orders to temporary collection
Order = new Mongo.Collection();
Then, people submit their comments, phone, etc and order. I save it to collection Operations:
Operations.insert({
phone: "phone",
comment: "comment",
etc: "etc"
savedOrder: Order //<- Array, right? Or Object will be better?
});
Nice, but when i want to get stats by every product, in what Operations product have used. How can I search thru my Operations and find every operation with that product?
Or this way is bad? How real pro's made this in real world?
If I understand it well, here is a sample document as stored in your Operation collection:
{
clientRef: "john-001",
phone: "12345678",
other: "etc.",
savedOrder: {
"someMetadataAboutOrder": "...",
"lines" : [
{ qty: 1, itemRef: "XYZ001", unitPriceInCts: 1050, desc: "USB Pen Drive 8G" },
{ qty: 1, itemRef: "ABC002", unitPriceInCts: 19995, desc: "Entry level motherboard" },
]
}
},
{
clientRef: "paul-002",
phone: null,
other: "etc.",
savedOrder: {
"someMetadataAboutOrder": "...",
"lines" : [
{ qty: 3, itemRef: "XYZ001", unitPriceInCts: 950, desc: "USB Pen Drive 8G" },
]
}
},
Given that, to find all operations having item reference XYZ001 you simply have to query:
> db.operations.find({"savedOrder.lines.itemRef":"XYZ001"})
This will return the whole document. If instead you are only interested in the client reference (and operation _id), you will use a projection as an extra argument to find:
> db.operations.find({"savedOrder.lines.itemRef":"XYZ001"}, {"clientRef": 1})
{ "_id" : ObjectId("556f07b5d5f2fb3f94b8c179"), "clientRef" : "john-001" }
{ "_id" : ObjectId("556f07b5d5f2fb3f94b8c17a"), "clientRef" : "paul-002" }
If you need to perform multi-documents (incl. multi-embedded documents) operations, you should take a look at the aggregation framework:
For example, to calculate the total of an order:
> db.operations.aggregate([
{$match: { "_id" : ObjectId("556f07b5d5f2fb3f94b8c179") }},
{$unwind: "$savedOrder.lines" },
{$group: { _id: "$_id",
total: {$sum: {$multiply: ["$savedOrder.lines.qty",
"$savedOrder.lines.unitPriceInCts"]}}
}}
])
{ "_id" : ObjectId("556f07b5d5f2fb3f94b8c179"), "total" : 21045 }
I'm an eternal newbie, but since no answer is posted, I'll give it a try.
First, start by installing robomongo or a similar software, it will allow you to have a look at your collections directly in mongoDB (btw, the default port is 3001)
The way I deal with your kind of problem is by using the _id field. It is a field automatically generated by mongoDB, and you can safely use it as an ID for any item in your collections.
Your catalog collection should have a string array field called product where you find all your products collection items _id. Same thing for the operations: if an order is an array of products _id, you can do the same and store this array of products _id in your savedOrder field. Feel free to add more fields in savedOrder if necessary, e.g. you make an array of objects products with additional fields such as discount.
Concerning your queries code, I assume you will find all you need on the web as soon as you figure out what your structure is.
For example, if you have a product array in your savedorder array, you can pull it out like that:
Operations.find({_id: "your operation ID"},{"savedOrder.products":1)
Basically, you ask for all the products _id in a specific operation. If you have several savedOrders in only one operation, you can specify too the savedOrder _id, if you used the one you had in your local collection.
Operations.find({_id: "your_operation_ID", "savedOrder._id": "your_savedOrder_ID"},{"savedOrder.products":1)
ps: to bad-ass coders here, if I'm doing it wrong, please tell me.
I find an answer :) Of course, this is not a reveal for real professionals, but is a big step for me. Maybe my experience someone find useful. All magic in using correct mongo operators. Let solve this problem in pseudocode.
We have a structure like this:
Operations:
1. Operation: {
_id: <- Mongo create this unique for us
phone: "phone1",
comment: "comment1",
savedOrder: [
{
_id: <- and again
productId: <- whe should save our product ID from 'products'
name: "Banana",
quantity: 100
},
{
_id:,
productId: <- Another ID, that we should save if order
name: "apple",
quantity: 50
}
]
And if we want to know, in what Operation user take "banana", we should use mongoDB operator"elemMatch" in Mongo docs
db.getCollection('operations').find({}, {savedOrder: {$elemMatch:{productId: "f5mhs8c2pLnNNiC5v"}}});
In simple, we get documents our saved order have products with id that we want to find. I don't know is it the best way, but it works for me :) Thank you!

Getting value from MongoDB query

I'm a new user to MongoDB.
When I do a find() on a db.users, I get back an object like such:
{"_id" : ObjectId("5373c8779c82e0955aadcddc"), "username": "example"}
How do I link this document to another document? I'm using the command line mongo shell.
For example, I want to associate a person in db.person with an attribute owner in a car object in db.car.
so it sounds like you're trying to do a join, which mongo does not support. what it does support is embedding. so, based on what you're trying to do, you could embed a list of cars that a person owns... for example:
{
id: (whatever),
username: phil,
cars: [
{make: honda, model: civic, mileage: 44000},
{make: ford, model: focus, mileage: 56000}
]
}
or, you could link to a list of IDs in your car collection:
{
id: (whatever),
username: phil,
cars: [
123,
456
]
}
however this is less efficient, since you'll have to do more finds to get each car's info-- which is why embedding rocks!
This is described in detail here: MongoDB relationships: embed or reference?

MongoDB: Updating a document in an array

I have a collection with documents of this schema:
{
_id: something,
recipients: [{id:1, name:"Andrey", isread:false}, {id:2, name:"John", isread:false}]
}
Now, I want to update "isread" for John (id = 2) using findAndModify(), because I also need to get the original document.
I'm trying this command:
db.messages.findAndModify({query:{'recipients.id':2}, update:{'recipients.$.isread':true}})
but what it does, it just replaces the whole "recipients" field with 'recipients.$.isread', so the document now looks like:
{
_id: someid,
'recipients.$.isread':true
}
What am I doing wrong?
Try to use $set like this:
db.messages.findAndModify({query:{'recipients.id':2}, update:{$set:{'recipients.$.isread':true}}})