I have one collection like
"_id": ObjectId("58e33b757100a1e4543f9c5c"),
"job_title": "Internship Job",
"category_list": [
"58de55747100a126748b4567",
"570660fca88ae1415a3c9869",
"5706645ea88ae1117a3c9869"
]
in the above collection category ids are from another collection of ObjectIds
Now i want to map this ids to category collection ids
simply i want category name instead of category ids by using PHP please can one help me out
Several things you can try:
DBRef. You can think it as a shortcut of doing your loop. Only difference is it's done by MongoDB. So it's going to be slow, but convenient.
You can also try $lookup. However it doesn't work for sharded cluster for now.
Data model design in MongoDB is mostly a matter of "balance". You can forget about normalization, just do whatever fits your use case best. In your case, consider embedding category name into your collection would probably make more sense since category name usually doesn't change very frequently. Thus you would mostly benefit from embedding. Rarely suffer from it. Once you do, the worst case is to update all category names.
The above assumption is based on the fact that "category name doesn't change frequently". It might not be real. So analyse base on your fact, how you do CRUD to the data? How frequently do you do them? Then try to find the model works best for your use case.
A good start would be reading the documentation data model design.
Related
I'm new to Mongodb (using PHP) and being that I'm used to RDMS I have what maybe a newbie question. I have a collection of "pages" that have a field called "tags" in which I have a series of tags, "happy, sad, angry, irtated".
Now I have another collection, called... let's say "users" and I want the user to be able to specify which tags are important to them... so this collection also has a field called "tags" in which I would have maybe, "Happy, and irtated"
Now... here comes the question, let's say I wanted to correct the spelling of irtated in both collections. Normally the RDMS world, I would have referenced these to a single table and then done an innerjoin such that changing the value in one spot would cascade everywhere... Or let say I wanted to remove a tag from the system... say, I didn't want Happy to be used anymore and I wanted to just remove it from all my collections where it exists...
Thoughts?
Why are you using Mongodb instead of RDBMS? most probably you want higher speed. Since in mongodb most related data in one place (in storage devices) so it is easy to retrieve data.That's why we keep same data in different places (Data redundancy). But when it comes to your case you need to keep more time to do the programming to do the same over RDBMS. So both RDBMS and NOSQL have their won pros and cons, and you will never have both profit from one account(Mongodb).
I'm facing to an issue with Doctrine relation and DDD.
I already searched a lot but I didn't find a suitable answer.
Let's take a simple example:
I have an aggregate Category and an aggregate Product.
I would like to have a ManyToOne relation between Product and Category.
Unfortunately Doctrine makes me add an attribute $category in my Product. But as Vaughn Vernon said, aggregate should reference to other aggregate by his identity, not by the aggregate itself.
Moreover even if I do this, Doctrine overwrites category_id to null if I don't set $category.
My only solution, at this moment, it's to add category_id field in mapping definition and add foreign key by myself.
Is there any other solution ?
I suspect you maybe trying to use the wrong tool for the job. Doctrine 2 is an Object Relational Manager hence it focuses on objects. If you read through the docs you won't find very much on domain driven design.
Given that Doctrine focuses on objects then:
$category = $product->getCategory();
Makes perfect sense. It also maps nicely onto how sql is designed to work.
If you really want a property Product::CategoryId then go ahead and add it. The latest Doctrine even has limited support for value objects.
But if you then want to somehow access the actual category object then you will need to add in your own query somehow. Kind of makes the orm code pretty much useless as you would be handing your own relations. Maybe drop down to pdo or the database access layer.
I have seen a few articles trying to do what you want but they barely manage the simplest cases and are impractical for any kind of production scenarios. Especially since DDD implies complex business logic.
I just would add a property categoryId to Product and that's it.
So I can't navigate from Product to Category directly, but instead I would need the CategoryRepository to fetch the respective category object, if I need it.
I lose the lazy loading convenience, but the aggregates are separated clean and nice.
According to this article Managing hierarchical data in mysql the most suitable solution for holding regular hierarchical data is a Nested Set Model, which i totaly like, but unfortunately my task is slightly more difficult. I need to manage a hierarchical model where some of the sub-categories may have multiple parents, something like crossing sets. Similiar problems described here.
To be exact i have some structure of categories in which each item can belong to multiple categories (and also on my way i'll need to provide some mean of category inheritance, if item belongs to TVs then it also belongs to Home_electronics, so the regular tag-cloud won't do here).
tl;dr: need a simple way / approach (maybe complex in realization, but simple in managment, like delete, add and find path) to manage model of categories with M:M relations.
Sadly i'm limited to MySQL only, but if this task can't be solved with SQL only, i'll move on to implementing this functionality in PHP (and thus i'll be glad to hear any out-of-the-box solutions of this problem - libraries or just sources, but thats for the worst case scenario).
Looks like the thing i'm looking for is named Directed Acyclic Graph (which was pretty obvious but i was probably too dumb to think about it :)).
It'll be good to see some implementation of it which has good managability.
And by the way, regular ID, ParentID, Data thing is not an option because MySQL doesn't have recursion and thus can't retrieve data by one query (well it can if you make PHP create a query with 1000 JOINs and pass it to MySQL, but thats retarded).
PS: Using only MySQL is not my decision, it's simply given, i know that any NoSQL DBMS would be more suitable.
Shouldn't a M to N type relationship tables in mysql work?
tbl_Category
cat_id, name
tbl_Cat_parent
cat_id, parent_cat_id
where parent_cat_id refers to Category->cat_id
In my MVC web app, I'm finding myself doing a lot of actions with ActiveRecords where I'll fetch a specific subset of Products from the database (for a search query, say), and then loop through again to display each one -- but to display each one requires several more trips to the database, to fetch things like price, who supplies them, and various other pieces of metadata. To calculate each of these pieces of metadata isn't very simple; it's not really something that could be achieved with a simple JOIN. However, it WOULD be possible (for most of these cases anyway) to batch the required database calls and do them all at once before the loop, and then within the loop refer to those pre-fetched data to do the various calculations.
Just as an example of the type of thing -- in a search, I might want to know what regions the product is provided by. In the database I have various rows which represent a particular supplier's stock of that item, and I can look up all the different suppliers which supply that item, and then get all the regions supplied by those suppliers. That fits nicely into one query, but it would start getting a bit complex to join into the original product search (wouldn't it?).
I have two questions:
does anyone else do something similar to this, and does it sound like a good way to handle the problem? Or does it sound more like a design problem (perhaps the application has grown out of ActiveRecord's usefulness, or perhaps the models need to be split up and combined in different ways, for instance).
If I do pre-fetch a bunch of different things I think I'll use inside the loop, I'm having a hard time deciding what would be the best way to pass the appropriate data back to the model. At the moment I'm using a static method on the model to fetch all the data I need at the start of the array, like fetchRegionsForProductIds(array $ids) and so forth; these methods return an array keyed by the ID of the product, so when I'm working inside the loop I can get the regions for the current product and pass them as a parameter to the model method that needs them. But that seems kind of hacky and laborious to me. So, can anyone tell me if there is just some really obvious and beautiful design pattern I'm missing which could totally resolve this for me, or if it's just a bit of a complex problem that needs a kind of ugly complex solution?
Small update: I wonder if using a datamapper class would put me on the right track? Is there a common way of implementing a data mapper so that it can be told to do large batch queries up front, store that information in an array, and then drip feed it out to the records as they request it?
I really hope this question makes sense; I've done the best I can to make it clear, and will happily add more detail if someone thinks they can have a go at it!
I'm using a self constructed database model. This model is constructed for a webshop application. this is how it looks like:
First of all I have a table for my products. This contains only general data like id and articlenr, for all of the product attributes (like name, price,etc) I have made seperate tables per type, so I have the following tables :
product_att_varchar
product_att_decimal
product_att_int
product_att_select
product_att_text
product_att_date
these tables are related by a relational table procuct_att_relational
My problem is the performance of this structure, if I want all the attributes of a specific product if have to use so much joins that it will slow down very much.
Does anyone have a solution for this???
Thanks
This model is called EAV (entity-attribute-value) and has its drawbacks and benefits.
Benefits are that it's very flexible and can be extended easily. It may be useful if you have very large number of very sparse attributes, the attributes cannot be predicted at design time (say, user-provided), or the attributes that are rarely used.
The drawbacks are performance and inability to index several attributes at the same time. However, if your database system allows indexed views (like SQL Server) or clustered storage of multiple tables (like Oracle), then by using these techniques performance can be improved.
However, storing all attributes in one record will still be faster.
I don't see any good reason to move those attributes out of the product table. It'd be one thing if you did it because you had some data that suggested a problem, but it looks like you thought "this will be better". Why did you do it this way right off the bat?
If you did it this way because it was generated for you, I'd recommend abandoning that generator.
People keep coming back to this model because they think it's "flexible". Well, it is I suppose, but that flexibility comes at a huge price: Every update and every query is slow and complex. Quassnoi mentions that if the attributes are sparse, i.e. most entity instances have only a small percentage of the possible attributes, this can save space. This is true, but the flip side is that if it is not sparse, this takes hugely more space, because now you have to store the attribute name or code for every attribute in addition to the value, plus you need to repeat some sort of key to identify the logical entity instance for every attribute.
The only time I can think of when this would be a good idea is if the list of attributes needs to be updatable on the fly, that is, a user needs to be able to decide to create a new attribute whenever he likes. But then what will the system do with this attribute? If you just want the user to be able to type it in and then later retrieve what he typed, easy enough. But will it affect processing in any way? Like, if the user decides to add a "clearance sale code", how will your program know how this affects the sale price? It could be done of course: You could have additional screens where the user enters data that somehow describes how each field affects pricing or re-ordering or whatever. But that would add yet more layers of complexity.
So my short answer is: Unless you have a very specialized requirement, don't do this. If you are trying to build a database describing items that you sell, with things like description and price and and quantity on hand, then create one table with fields like description and price and quantity on hand. Life is hard enough without going out of your way to make it harder.