Meteor.js embedded collections - meteor

Data model:
{
name: "Some name",
items: ["Item1", "Item2", "Item3"]
}
I want to publish all the name fields into a collection (this I can do), let's call it names, and once the user selects something from names, publish the items array into another Meteor collection called items.
The reason for this is that I need names to be always available and items should only be relevant to the user's selection.
How can this be achieved? Maybe there's another way to do this, e.g. selectively update only a part of an item in a collection?

This is a very common model in Meteor and Mongo. You can solve it in two major ways.
If the number of items per name is going to be small, just put them into an array inside the name document. They will be automatically available to you whenever you load a name.
If the number of items per name could be very large, then create two collections, Names and Items. In the the Items collection include a key nameId and fill it with the name. Then when you load a name document you can simply find the related items with Items.find({ nameId: _idOfMyNameDocument })
You may also find the reywood:publish-composite package helpful.

Related

How to provide drop-down list of a specific resource types to choose from with ARM template

I'm trying to create an ARM template which queries the list of resources (i.e. Cosmos DB instances) in the selected resource group so the user can pick from the list. I then want to use the selected resource to get a property and use it elsewhere in the template.
I don't want the user to have to know the resource name and type it in, rather I'd prefer to produce a list to choose from.
I've tried using a parameter type of string or array along with the [list(resourceId('<id>', resourceGroup().name, '<date>')] but it doesn't produce a drop-down list.
Is this even possible?

How to delete records from a model referenced by a different model?

I have two models, where model A references items in model B. When I delete items from model B, react rerenders before I can update model A to also delete the referenced items.
Example:
I have a feed. The feed is made up of different types of items. Each type of item is stored in its respective model.
The feed order is stored as an array of item IDs, referencing the items in their different substores.
I have made a minimal failing example here. The issue occurs after clicking the button three times
https://codesandbox.io/s/deleting-referenced-items-kmw1e
The key line is
else console.error(">>>> feed order contains deleted item", id);
It's problematic that the feed order might contain deleted items because it could mean there is a programming error that resulted in bad references. In this case it's not a programming error, the second store just hasn't updated yet.
Is there a way I might be able to batch the createAndDeleteTodo, to not evaluate all listeners until the entire thunk and all subthunks have completed?
In the above example it's trivial enough to just have one master action which updates the feed order and the items but it would feel cumbersome if there was more than just one type of item as each item type lives in it's own respective model.
The same thunk action is triggering multiple Actions. And as per the definition of useStoreState:
The useStoreState will execute any time an update to your store's state occurs
So, in effect, when you do this inside the thunk:
actions.setTodos({ newTodos: [newTodo], todoToDelete });
actions.updateFeedOrder({ newTodos: [newTodo], todoToDelete });
there are two actions being dispatched and those would account for a separate store state change event listener. You will get multiple render calls for the multiple store updates.
You have two options:
Either club those actions into one as shown in the example: https://codesandbox.io/s/so-deleting-referenced-items-forked-x4d7v
OR check the useStoreState method for a case on handling the render only when both the store values are matching the count
It seems the problem is that you're dispatching to redux store 2 times. First when you create new items and then when you delete them.
I'd suggest to do it this way:
Create a deep copy of object/array you wanna work with.
Make both operations on that copy.
Dispatch that value to the store.
This way nothing will be rerendered until both operations are finished.

Organizing a Cloud Firestore database

I can't manage to determine what is the better way of organizing my database for my app :
My users can create items identified by a unique ID.
The queries I need :
- Query 1: Get all the items created by a user
- Query 2 : From the UID of an item, get its creator
My database is organized as following :
Users database
user1 : {
item1_uid,
item2_uid
},
user2 : {
item3_uid
}
Items database
item1_uid : {
title,
description
},
item2_uid : {
title,
description
},
item3_uid : {
title,
description
}
For the query 2, its quite simple but for the query 2, I need to parse all the users database and list all the items Id to see if there is the one I am looking for. It works right now but I'm afraid that it will slow the request time as the database grows.
Should I add in the items data a row with the user id ? If yes the query will be simpler but I heard that I am not supposed to have twice the same data in the database because it can lead to conflicts when adding or removing items.
Should I add in the items data a row with the user id ?
Yes, this is a very common approach in the NoSQL world and is called denormalization. Denormalization is described, in this "famous" post about NoSQL data modeling, as "copying of the same data into multiple documents in order to simplify/optimize query processing or to fit the user’s data into a particular data model". In other words, the main driver of your data model design is the queries you plan to execute.
More concretely you could have an extra field in your item documents, which contain the ID of the creator. You could even have another one with, e.g., the name of the creator: This way, in one query, you can display the items and their creators.
Now, for maintaining these different documents in sync (for example, if you change the name of one user, you want it to be updated in the corresponding items), you can either use a Batched Write to modify several documents in one atomic operation, or rely on one or more Cloud Functions that would detect the changes of the user documents and reflect them in the item documents.

React / Redux: single source of truth when navigating into a details view

I have an architectural / best practices question regarding react and redux.
I'm using redux middleware to query a graphql service and expose the result in props to connected components. One of the advantages of graphql is being able to retrieve only the information you need using their query format.
I have a page that lists entities and when you click a specific entity you get a view entity detail page with the id in the query string.
I want an array of entities in my state to be my single source of truth and a selectedEntityId property to serve as a lookup on that list of entities.
My problem is that the list of entities in the list page is just the name and description while the view page contains much much more information.
Solutions I can think of:
1) Retrieve all the entities information (not just name and description) in the list page (and view page). The problem is that I'd be querying a bunch of information I don't need on the list page which goes against the idea of graphql.
2) Have 2 properties on my state. One will contain entities with just name and description while the other property will contain a list of entities with more information. The problem with this solution is that I have 2 single sources of truth.
3) I can "marry" the 2 entity lists, so if I navigate from a list to a view page, I can saturate the list of entities I already have from the list page with the entities I get from the view page (the entities with many more properties besides name and description) and use that list as my single source of truth. This seems to be the best solution but I don't know a clean way to do this.
Can anyone shed light on the situation?
Thanks!
I'm not sure if thats the best one, but based on your solutions, I would say the third works alright.
You could try adding a new value to each list item that identifies if the specific item has all the details or not.
Imagine the store like so:
items: {
id1: {
isFull: false,
title: 'Item 1',
id: 'id1'
},
id2: {
isFull: true,
title: 'Item 2',
id: 'id2',
description: '..',
lorem: '',
...
}
}
Then get isFull in the details page and fetch in case of false.

Voting on items - how to design database/aws-lambda to minimize AWS costs

I'm working on a website that mostly displays items created by registered users. So I'd say 95% of API calls are to read a single item and 5% are to store a single item. System is designed with AWS API Gateway that calls AWS Lambda function which manipulates data in DynamoDB.
My next step is to implement voting system (upvote/downvote) with basic fetaures:
Each registered user can vote only once per item, and later is only allowed to change that vote.
number of votes needs to be displayed to all users next to every item.
items have only single-item views, and are (almost) never displayed in a list view.
only list view I need is "top 100 items by votes" but it is ok to calculate this once per day and serve cached version
My goal is to design a database/lambda to minimize costs of AWS. It's easy to make the logic work but I'm not sure if my solution is the optimal one:
My items table currently has hashkey slug and sortkey version
I created items-votes table with hashkey slug and sortkey user and also voted field (containing -1 or 1)
I added field votes to items table
API call to upvote/downvote inserts to item-votes table but before checks constraints that user has not already voted that way. Then in second query updates items table with updated votes count. (so 1 API call and 2 db queries)
old API call to show an item stays the same but grabs new votes count too (1 API call and 1 db query)
I was wondering if this can be done even better with avoiding new items-votes table and storing user votes inside items table? It looks like it is possible to save one query that way, and half the lambda execution time but I'm worried it might make that table too big/complex. Each user field is a 10 chars user ID so if item gets thousands of votes I'm not sure how Lambda/DynamoDB will behave compared to original solution.
I don't expect thousands of votes any time soon, but it is not impossible to happen to a few items and I'd like to avoid situation where I need to migrate to different solution in the near future.
I would suggest to have a SET DynamoDB (i.e. SS) attribute to maintain the list of users who voted against the item. Something like below:-
upvotes : ['user1', 'user2']
downvotes : ['user1', 'user2']
When you update the votes using UpdateExpression, you can use ADD operator which adds users to SET only if it doesn't exists.
ADD - Adds the specified value to the item, if the attribute does not
already exist. If the attribute does exist, then the behavior of ADD
depends on the data type of the attribute:
If the existing data type is a set and if Value is also a set, then
Value is added to the existing set. For example, if the attribute
value is the set [1,2], and the ADD action specified [3], then the
final attribute value is [1,2,3]. An error occurs if an ADD action is
specified for a set attribute and the attribute type specified does
not match the existing set type. Both sets must have the same
primitive data type. For example, if the existing data type is a set
of strings, the Value must also be a set of strings.
This way you don't need to check whether the user already upvote or downvote for the item or not.
Only thing you may need to ensure is that the same user shouldn't be present on upvote and downvote set. Probably, you can use REMOVE or ConditionExpression to achieve this.

Resources