loopback performance with complex query - performance

if I have models connected it is better for the client to return the whole chain or it is more appropriate for the client to request the various sections.
es price list -> products (it could be even more complex)
it is better to make the query on the price list that also brings the products or it is the client who must request the products for that price list.

Related

How do i satisfy business requirements across microservices with immediate consistenc?

Let’s assume I’m in the context of an admin panel for a webshop. I have a list of orders. Those orders are payed for and are ready to ship. The (admin) user would like to start making shipments based on the items ordered.
Imagine there are 2 microservices. One for orders and one for shipments. In order to create a shipment, i will send a request with a couple of items to be shipped and an order ID to the shipment service. The shipment service will then check whether the items are present in the order by querying the order service. Because i don’t want to create a shipment with items that are not present in the order.
I’d like to have immediate consistency because the shipment data will be send to a third-party application after creation. Thereby it also feels weird to allow shipments to be created if the data is not correct.
I’m also using GraphQL mutations. Which means i have to return the updated state to the user, which also makes eventual consistency a lot harder.
What is the recommended approach for these situations? Could this be a sign that these 2 microservices need to be merged? I can imagine this situation can occur multiple times.

Coupling in microservices architecture

When working on an application in microservices architecture I stumbled upon issues concerning coupling between services.
This a typical application for ordering products. It seams reasonable to have a service that will operate as a product catalog. Our JavaScript client can ask this service for available products and show them in browser. When user clicks on a product we have to create an order. We would like to manage orders in another service. So an order is created - it means that user X ordered product Y. On the technical level we are simply persisting user id and product id in a database.
To sum up we have:
Products service
Product class:
Product ID, Product Name
Orders service
Order class:
Order ID, Product ID, User ID, Order date
Now let's imagine following scenario - in JavaScript client we would like to list all products that user have ordered. Orders service provides a list of products ids for a given user. But user cares about product name, not the id. Unfortunately Orders service doesn't know anything about products names.
We could tackle this in couple of ways:
Simply assume that the client is responsible for getting the information it needs. So after it calls Orders service and gets a list of products ids, it performs another call to Products service, passing products ids and getting corresponding products names in response. Then the client assembles both responses into something useful. This approach keeps our services clean, without leaking of domain knowledge from one service to another. But it requires more work on the client side.
Orders service when asked for ordered products makes a call on the backend to the Products service. It retrieves product names, assembles a response that contains orderDate and productName and sends that to client. All that's left for client to do is to present the data. Downside of this approach is that Orders service now gains more knowledge about products than neccessary.
Duplicate information about product name in Orders service. When an order is created, we pass not only product id but also product name. That means that Order class will look like this:
Order class:
Order ID, Product ID, Product name, User ID, Order date
Now we can easly provide full information about order without additional call to Products service. Also this time Orders service has too much knowledge about products. What's beneficial tough is that Orders service can provide relevant data even if Products service is down.
Could any of these approaches be considered best practice? Or are there different solutions?
In the eShopOnContainers example( https://github.com/dotnet-architecture/eShopOnContainers ), they add the following fields at the time an order item is created:
public void AddOrderItem(int productId, string productName, decimal unitPrice, decimal discount, string pictureUrl, int units = 1)
This duplicates the catalog information, however as this is a point in time snapshot of the record. This is far safer than linking to the original data.
At this point in the user journey you are in the domain of an order, if a user is viewing an order you can provide a link to the catalogue. However, the order service should be able to operate independently. Linking back to the catalogue for the information on products prevents the Order service owning it's own data.
A nightmare scenario being that a price changes in the catalogue... What would happen to the historic orders?

Sorting elasticsearch types based on child type property

I'm working on a e-commerce search page and need to free text search products and have multiple facet options and sorting capabilities. The issue I'm facing has to do with product prices:
One product has multiple prices - there are special discounts, B2B customer specific prices, and specific B2C prices. There could be a few hundred prices per product.
I need to be able to do to a full text search on products, but still be able to sort on one of the selected price groups.
My initial though would be to put all of the prices into the product item, but that means I'll need to update the product objects in the index every time a price changes - which is often. This will also make the objects quite big.
I see that elasticsearch now has the capability of HasParent/HasChildren queries, but I am not sure if that is the right way to go, or if it even is possible.
Is it possible to keep prices as a separate type outside the product type and use the HasParent/HasChilden queries to sort the procuts on the price?
My initial though would be to put all of the prices into the product item, but that means I'll need to update the product objects in the index every time a price changes - which is often. This will also make the objects quite big.
I would personally be inclined not to store complex pricing data within Elasticsearch, at least not prices calculated by business logic such as discounts and specific B2C prices.
A base price could be stored for querying and sorting, and apply pricing logic to this with scripting, using script queries and script sorting, respectively.
I see that elasticsearch now has the capability of HasParent/HasChildren queries, but I am not sure if that is the right way to go, or if it even is possible. Is it possible to keep prices as a separate type outside the product type and use the HasParent/HasChilden queries to sort the procuts on the price?
Parent/Child relationships operate on documents within a single index, with a join datatype field on a document to indicate the relationship between a parent and a child, and child documents indexed on the same shard as the parent. If children are not evenly distributed across parents/shards e.g. one parent document has a million children and the others have only a few each, it's possible to end up with hot spots within shards that can affect performance. Product and pricing data doesn't feel like a good fit for Parent/Child; pricing sounds like it's too dynamic to be stored within documents.

Search strategy for online application

I have an application with around 700 000 active products with actual stock quantity.
Each product can have multiple attributes and categories.
Product name, description and attributes can be delivered to the user in a few languages.
What I need to achive is fast search. By fast I mean that for example for product group which contains 250k of products I would like to return a first page of sorted results in 100ms.
My first thought was to deformalize data and push it into document db like elastic search. But there is one issue - product price: it depends on the user that is actually logged in.
Currently there will be 30k users. Each user can have different discount for each product category or even for each particular product. When discount or price is changed there is a business requirement to synchronize prices in a few minutes. Potentially system could compute prices for search results on fly, but there is an issue with sorting and pagination. When group consist of 250k products it will be hard to get results, compute price, sort and return given page.
Is there any way to return user dependent field in elastic search? Or I should rather start looking into some other solutions like graph databases?

250000 Grouped products in Magento

I've started working on a new Magento webshop which has roughly 250000 different products. Each product can have different conditions (new, used, damaged, etc., each with their own price.). Magento doesn't seem to have a method to implement this at the moment. Of those 250000 products, there are about 150000 different conditions in stock and another 150000 conditions which aren't in stock but do have a price (which can be put on the wishlist).
Some numbers: 1500 categories, drop down attributes (country) with > 300 options, integer attributes (year). Starting with two websites 6 languages each.
I've thought out two solutions to solve this problem:
Grouped / Simple product structure
We create a grouped product which is the container product, each condition will be a different simple product. We'll relate these products to the grouped product.
The nice thing about this solution is that is pretty easy to implement, we'll have to import the data in the correct way and all the information is exactly presented in the way we want.
New Product type
We create a new product type which can have multiple conditions, each with their own inventory. On checkout the inventory is substracted. The problem with this is that implementing the CatalogInventory model in this way probably is difficult and building a whole product type is time consuming and bugprone in general.
The advantage of this solution is this that there will be about 2-2.5x times less products in the system.
Others
Are there any other options to solve this? Maybe there is a module that does all this?
In conclusion: Of course I prefer the first solution but can Magento handle that? Does anyone have experience with this much Grouped Products? The system will have about 550000 products (grouped + simple) products in the system, what will be the performance implications of this? What happens when the site grows and we'll have twice the amount of products?
Without knowing more details I'd lean towards using a new product type or just adding the feature independently of product types if you have a use for configurable products (I definitely wouldn't try to duplicate the configurable product type). I'd disable inventory management and use some additional tables which hold individual item inventory with the per-item conditions and maintain a separate inventory that way. Use events and overrides to control the CatalogInventory stock status as needed. Creating new products constantly which are largely duplicates seems like a hassle worth avoiding if this is a long-term endeavor that needs to scale.
However, the Grouped/Simple method might be a viable short-term solution and appropriate if the project is in it's early stages and can't afford a huge initial expenditure. If well-planned, a script should be able to convert all of the old grouped/simple products into your new product type when ready to launch.

Resources