I am writing a vocabulary learning application.
I have a Wordset Entity.
I want it to contain a property - WordsToLearn (a collection of words to learn for a CURRENT user, words which are either new, i.e no repetitions for current user or have Repetition due today or earlier)
How can I implement this?
Without this my object seems very incomplete.
Are entities limited to simple relationships and I should forget about it in this place and move it to Wordset Repository.
I would be very useful to be able to get that information (wordsToLearn) from Wordset Object
Yes, entities are limited to these simple relationships. For more complex queries you have to use a WordsetRepository that you can pass your current_user object to and use that to get the desired entities in your controllers. You can use Doctrine's DQL to fetch 'real' entity objects instead of just SQL results.
Related
I am trying to come up one-many relationship where an user can have links to many organization bucket.
I would like to walk and return the results back.
I am upgrading the stackmob's scala driver to support linkwalking https://github.com/megamsys/scaliak
Any help would be greatly be appreciated. The forums talk about using mapreduce.
Link walking is deprecated in the latest version of Riak, and will likely be removed in future versions. So it probably doesn't make sense to upgrade the Scala driver to support it.
The real question here is - how should you model a One to Many relationship in Riak? There are two main approaches to this, depending on if you have a read-heavy or a write-heavy use case.
1 - Links as Lists of Keys
You can store the list of links/associations as a separate object for easy retrieval. For example, if I have a users object stored at /buckets/users/keys/user-id-123:
{ id: "user-id-123", name: "Dmitri", ... }
I can then store the organizations that user belongs to (notice that I'm using the same key for the user and for their membership object) in /buckets/user-orgs/keys/user-id-123:
["organization-id-1", "organization-id-2", "organization-id-3"]
This allows me to answer the question of "Which organizations does this user belong to?" with a single GET to the user-orgs object (and, optionally, a multi-get to fetch each of the organization objects by their IDs).
Note: If you're using Riak 2.0 or above, you can use the new Riak Data Types (specifically, the sets data type), to store that list of IDs. (The Sets data type provides an API of operations to add/remove/fetch elements from a list in a way appropriate for distributed systems).
Use this approach when you have a read-heavy use case (when the list of links is read frequently, but is not written to/updated frequently).
2 - Search / Query for the links
The other main approach is to use indexes (preferably via the Solr-based Riak Search, or, for rare cases, via Secondary Indexes) and queries to retrieve one-to-many association objects.
So, if you had a user object stored at /buckets/users/keys/user-id-123:
{ id: "user-id-123", name: "Dmitri", ... }
You would then insert multiple "membership entry" objects into the search-enabled (meaning, you would create a search index and associate it with the user-orgs bucket) /buckets/user-orgs/:
{user_id: "user-id-123", org_id: "organization-1"}
{user_id: "user-id-123", org_id: "organization-2"}
{user_id: "user-id-123", org_id: "organization-3"}
Afterwards, you can answer the question "Which organizations does the user belong to?" by issuing a Search query saying "Give me all of the objects in user-orgs where user_id equals to user-id-123", for example.
Incidentally, using Search / membership objects like this also allows you to model a Many-To-Many relationship (meaning, you can also answer the question "Which users belong to the organization organization-id-1?").
Because Search queries are more expensive than a single GET to fetch a membership list (like in the first strategy), you should use this strategy when you're not in a read-heavy use case (when the membership objects are updated often, but not read often), or when you need to also model the inverse relationship (many to many).
Note: Do not use Map/Reduce to model one-to-many relationships, and don't use the deprecated Link Walking mechanism (which uses Map/Reduce on the backend, anyways).
I have two entities, User and Place, and have a many-to-many relationship between them in order to facilitate the concept of a user favoriting a place.
As part of the feature, I would like for the Place entity to contain a field which gives me the total number of users who have favorited it. I do not need the user entities themselves.
Reading the documentation, I've found several solutions, but I don't particularly like any of them.
Aggregate Field
Using this solution, I would simply define an integer field on the Venue entity that is updated as favorites are added and removed. Thus, the value is not calculated on-the-fly and instead is retrieved as any other field would be.
I dislike this approach as there are issues with concurrency and it makes the concept unnecessarily complex to manage in code.
Eager Loading
Using this method, I would eagerly load the relationship as a bidirectional association so that the Place would load each User entity that has favorited it as part of the initial querying process. To get the count, I simply ask the collection for its count().
This results in fewer queries, but the amount of data retrieved is too much and does not scale well over time.
Extra Lazy Loading
This is what I am currently using. It is similar to the Eager Loading solution in that I ensure the relationship is bi-directional and simply ask the collection for its count(), but using the extra lazy fetch mode doctrine is intelligent enough to only issue a COUNT() query rather than retrieve the entire list of users associated with the Place entity.
The drawback here is that if I am loading N Place entities, I need N+1 queries as each Place will issue a separate COUNT() query.
Ideal Solution
My ideal solution would be to find a way to tell Doctrine to perform the first query to load the collection and then a second query to load all counts for the IDs within the collection and then populate the fields in their respective entities.
I have not found a way to do this easily.
Does anyone have any examples of this or are there other solutions for solving this problem that I may be overlooking?
if you know how to write your query in sql, you can do it in doctrine.
see this answer for reference:
Symfony2, Doctrine2 query - select with IF and COUNT
You can run a similar DQL:
SELECT p place, COUNT(u) cnt FROM YourBundle:Place p
LEFT JOIN p.users u
Note that results array elements are in the form (each is an array):
array(
'place' => your hydrated object (in your case the place),
'cnt' => your aggregated field (in your case the number of users),
)
Should I be using entity_load or EntityFieldQuery to get entity ids from a custom entity?
I was going to use entity_load to pull all of the entities in question of a particular type, and grab their relevant information (but that seems like it could be inefficient).
EntityFieldQuery will only return an array of entity IDs. If that is all you need then EntityFieldQuery will be much faster.
If you need to get the field values you should do entity_load. It is slow but it is the Drupal way.
If it is a very large number of nodes you may have timeout issues. To overcome this use Drupals Batch API or you can use the Database API to write a custom query to pull in the exact data you need in one query. This is technically faster but requires more code and can break compatibility.
I am studying https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/working-with-associations.html but I cannot figure out what cascade merge does. I have seen elsewhere that
$new_object = $em->merge($object);
basically creates a new managed object based on $object. Is that correct?
$em->merge() is used to take an Entity which has been taken out of the context of the entity manager and 'reattach it'.
If the Entity was never managed, merge is equivalent to persist.
If the Entity was detached, or serialized (put in a cache perhaps) then merge more or less looks up the id of the entity in the data store and then starts tracking any changes to the entity from that point on.
Cascading a merge extends this behavior to associated entities of the one you are merging. This means that changes are cascaded to the associations and not just the entity being merged.
I know this is an old question, but I think it is worth mentioning that $em->merge() is deprecated and will be removed soon. Check here
Merge operation is deprecated and will be removed in Persistence 2.0.
Merging should be part of the business domain of an application rather
than a generic operation of ObjectManager.
Also please read this doc v3 how they expect entities to be stored
https://www.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/entities-in-session.html#entities-in-the-session
It is a good idea to avoid storing entities in serialized formats such
as $_SESSION: instead, store the entity identifiers or raw data.
In an n-tiered application where you are using custom entities, how do you find yourself handling data needed from lookup tables? Do you create entities for each of these lookup tables or employ some other strategy?
For example. I have a "Ratings" lookup table that will be used to populate a dropdownlist. Would you create a ratings object with a ratingid and rating property and pass that to your UI or is there a more efficient way to go about it?
Appreciate your thoughts.
I'd suggest that the solution will depend on how often the lookup data changes, whether or not it needs to be editable, and whether or not you're enforcing referential integrity at the database. I think it makes the schema more understandable if you put each lookup type into a separate table.
I generally don't create entities for each lookup table, but instead will load most of the common lookups into structures that are easily re-used by the application - for an asp.net app, for example, I'll create hashtables or ordered dictionaries which can easily be bound to most web controls.
And, horror of horrors, I sometimes create a singleton to manage access to all these lookups, which can be stored as static vars or in the cache, depending on requirements.
We seperate out the different look up types into different objects. It seems to be a little more work up front, but it provides us the ability to make changes to each individual object when we need to, such as an addition of additional information to an object.