How to fetch data from multi tables in nosql using SEMBAST plugin - flutter

I am not able to fetch data when multi table which are having relationship . so can any one help as per the below image
finally i need data like
ORDER_ID, USER_FULL_NAME, PRODUCT_NAME, PRODUCT_PRICE from 3 different table .
please help me out.

Sembast, does not provide a way to query multiple stores in one join query. However getting an entity by id (here a user or a product) is almost immediate (store.record(id).get(db) or store.records(ids).get(db)) so I think your best bet is to query the order_items store and fetch the users and products by ids.
Basically using 3 requests in a transaction to ensure data integrity should perform the join you want.

Related

How to avoid customer's order history being changed in MongoDB?

I have two collections
Customers
Products
I have a field called "orders" in each of my customer document and what this "orders" field does is that it stores a reference to the product Id which was ordered by a customer, now my question is since I'm referencing product Id and if I update the "title" of that product then it will also update in the customer's order history since I can't embed each order information since a customer may order thousands of products and it can hit 16mb mark in no time so what's the fix for this. Thanks.
Create an Orders Collection
Store ID of the user who made the order
Store ID of the product bought
I understand you are looking up the value of the product from the customer entity. You will always get the latest price if you are not storing the order/price historical transactions. Because your data model is designed this way to retrieve the latest price information.
My suggestion.
Orders place with product and price always need to be stored in history entity or like order lines and not allow any process to change it so that when you look up products that customers brought you can always get the historical price and price change of the product should not affect the previous order. Two options.
Store the order history in the current collection customers (or top say 50 order lines if you don't need all of history(write additional logic to handle this)
if "option1" is not feasible due to large no. of orders think of creating an order lines transaction table and refer order line for the product brought via DBref or lookup command.
Note: it would have helped if you have given no. of transactions in each collection currently and its expected rate of growth of documents in the collection QoQ.
You have orders and products. Orders are referencing products. Your problem is that the products get updated and now your orders reference the new product. The easiest way to combat this issue is to store full data in each order. Store all the key product-related information.
The advantage is that this kind of solution is extremely easy to visualize and implement. The disadvantage is that you have a lot of repetitive data since most of your products probably don't get updated.
If you store a product update history based on timestamps, then you could solve your problem. Products are identified now by 3 fields. The product ID, active start date and active end date. Or you could configure products in this way: product ID = product ID + "Version X" and store this version against each order.
If you use dates, then you will query for the product and find the product version that was active during the time period that the order occurred. If you use versions against the product, then you will simply query the database for the particular version of the product itself. I haven't used mongoDb so I'm not sure how you would achieve this in mongoDb exactly. Naively however, you can modify the product ID to include the version as well using # as a delimiter possibly.
The advantage of this solution is that you don't store too much of extra data. Considering that products won't be updated too often, I feel like this is the ideal solution to your problem

How to perform Model Joins + Condition on Relations in Sails.js?

How can I make a model join query(condition) and sort on relation models on Sails?
Example: I have 4 tables(collections in mongodb) and 4 related models in mongodb:
User: user_id, name
Follow: user_id, following_id (user id is being followed)
Point: user_id, point
Post: name, content, user_id, created_at
So from the post table, I want to make a query to find the posts of users that I'm following and sort by their point. Like this raw sql:
SELECT post.* FROM post
LEFT JOIN user_point up ON up.user_id = post.user_id
WHERE post.user_id IN (1,2,3,4) // assume I got my following_user_ids result is 1,2,3,4 for this case so no need to join follow table
ORDER BY up.point DESC // high point then first return
I don't know how can do this by Sails model? I have read many instructions by got no helps. Almost people said: Sails Association, but it just helps return the relation instead of do the where or order by to sort original model results(is this case: post).
I have worked with Yii2, a PHP framework so with this case I can do it easily:
Post::model()->leftJoin('user_point up', 'up.user_id = post.user_id')->where(['post.user_id' => [1,2,3,4])->orderBy(['up.point' => SORT_DESC])->all();
I'm stucked in Sails, very thanks if someone help me!!!
Because you're using Mongo, and because you need the full power of normal JOIN's, you will probably be forced to use some other ORM solution (i.e. mongodb package on npm) for queries like that.
Why? See the API documentation for sendNativeQuery(), which states native query features are only available for SQL-like DBMS's.

#BatchFetch type JOIN

I'm confused about this annotation for an entity field that is of type of another entity:
#BatchFetch(value = BatchFetchType.JOIN)
In the docs of EclipseLink for BatchFetch they explain it as following:
For example, consider an object with an EMPLOYEE and PHONE table in
which PHONE has a foreign key to EMPLOYEE. By default, reading a list
of employees' addresses by default requires n queries, for each
employee's address. With batch fetching, you use one query for all the
addresses.
but I'm confused about the meaning of specifying BatchFetchType.JOIN. I mean, doesn't BatchFetch do a join in the moment it retrieves the list of records associated with employee? The records of address/phone type are retrieved using the foreign key, so it is a join itself, right?
The BatchFetch type is an optional parameter, and for join it is said:
JOIN – The original query's selection criteria is joined with the
batch query
what does this means? Isn't the batch query a join itself?
Joining the relationship and returning the referenced data with the main data is a fetch join. So a query that brings in 1 Employee that has 5 phones, results in 5 rows being returned, with the data in Employee being duplicated for reach row. When that is less ideal, say a query over 1000 employees, you resort to a separate batch query for these phone numbers. Such a query would run once to return 1000 employee rows, and then run a second query to return all employee phones needed to build the read in employees.
The three batch query types listed here then determine how this second batch query gets built. These will perform differently based on the data and database tuning.
JOIN - Works much the same away a fetch join would, except it only returns the Phone data.
EXISTS - This causes the DB to execute the initial query on Employees, but uses the data in an Exists subquery to then fetch the Phones.
IN - EclipseLink agregates all the Employee IDs or values used to reference Phones, and uses them to filter Phones directly.
Best way to find out is always to try it out with SQL logging turned on to see what it generates for your mapping and query. Since these are performance options, you should test them out and record the metrics to determine which works best for your application as its dataset grows.

TSQL - Deleting with Inner Joins and multiple conditions

My question is a variation on one already asked and answered (TSQL Delete Using Inner Joins) but I have a different level of complexity and I couldn't see a solution to it.
My requirement is to delete Special Prices which haven't been accessed in 90 days. Special Prices are keyed on Customer ID and Product ID and the products have to matched to a Customer Order Detail table which also contains a Customer ID and a Product ID. I want to write one function that will look at the Special Price table for each Customer, compare each Product for that Customer with the Customer Order Detail table and if the Maximum Order Date is more than 90 days earlier than today, delete it from the Special Price table.
I know I can use a CURSOR (slow but effective) but would prefer to have a single query like the one in the TSQL Delete Using Inner Joins example. Any ideas and/or is more information required?
I cannot dig more on the situation of your system but i think and if it is ok for you, check MERGE STATEMENT, it might be a help instead of using cursors. check this Link MERGE STATEMENT

Imitate join for NoSQL document database

Are there any workarounds to execute join-like query with NoSQL document database?
Example: We need to select last month articles by users with rating more than thousand.
SQL solution is
SELECT a.* FROM Articles as a
INNER JOIN Users as u ON a.UserId = u.Id
WHERE a.Date > (Now - Month) AND u.Rating > 1000
I can imagine several NoSQL solutions. First is two queries solution:
Retrieve users with rating more than 1000
Retrieve last month articles for these users
I don't like it as I have to make two queries and I have to retrieve all users with rating > 1000 (what if I have 1kk of users?)
The other NoSQL solution which comes to my mind is denormalization. But I am not big fan of it. I would be not against of putting comments collection to post entity (because comments belong to post), but I don't like to put user inside article or articles inside user.
Are there any other solutions?
You can do that using Multi Maps / Reduce indexes with RavenDB. See here.
RavenDB Multi Maps handles this scenarios very well:
http://ayende.com/blog/89089/ravendb-multi-maps-reduce-indexes
Another solution may be playOrm where you can partition a table and select and join on partitions. IT is basically like hibernate with JQL and all except you query into partitions. Perhaps if you partition by month, you can run a simple old school select query on that partition and join it with something else. noSql now seems to have joins through playOrm ;). It of course does not do joins on HUGE tables. The PARTITION needs to be comparative size to RDBMS table sizes when doing joins....The table size can be infinite(ie. you have infinite partitions).