readFragment to return all object of a type - apollo-client

i'm using Apollo Client do request a very structured dataset from my server. Something like
-Show
id
title
...
-Seasons
number
-Episodes
id
number
airdate
Thanks to normalization my episodes are stored individually but i cannot query them. For exemple i would like to query all the episodes to then sort them by date to display coming next.
the only way i see is to either 'reduce' my show list to an array of episode and then do the filtering. Or to do a new query to the server.
But it will be so much faster if I could get a list of all Episodes in cache.
Unfortunately with readFragment you can only query One object by its id.
Question:
Is there a way to query the cache for all object of a defined type?

The answer is late, but could have helped someone else, currently apollo does not support it. This is the issue here from github, and also a work around.
https://github.com/apollographql/apollo-client/issues/4724#issuecomment-487373566
Here is the copied workaround by #superandrew213
const serializedState = client.cache.extract()
const typeNameItems = Object.values(serializedState)
.filter(item => item.__typename === 'TypeName')
.map(item => client.readFragment({
fragmentName: 'FragmentName',
fragment: Fragment,
id: item.id,
}))
Please take note that this method is slow, especially if you have a large normalized data.

Related

How do I negate a query in Parse's API (Back4App)? Specifically, how do I get everything not in a relation?

Does anyone know if there's an easy way to negate a parse query? Something like this:
Parse.Query.not(query)
More specifically I want to do a relational query that gets everything except for the objects within the query. For example:
const relation = myParseObject.relation("myRelation");
const query = relation.query();
const negatedQuery = Parse.Query.not(query);
return await negatedQuery.find();
I know one solution would be to fetch the objects in the relation and then create a new query by looping through the objectIds using query.notEqualTo("objectId", fetchedObjectIds[i]), but this seems really circuitous...
Any help would be much appreciated!
doesNotMatchKeyInQuery is the solution as Davi Macedo pointed out in the comments.
For example, if I wanted to get all of the Comments that are not in an Article's relation, I would do the following:
const relationQuery = article.relation("comments").query();
const notInRelationQuery = new Parse.Query("Comment");
notInRelationQuery.doesNotMatchKeyInQuery("objectId", "objectId", relationQuery);
const notRelatedComments = await notInRelationQuery.find();
How I understand it is that the first argument is specifying the key in the objects that we are fetching. The second argument is specifying the key in the objects that are in the query that we're about to argue. And lastly we argue a query for the objects we don't want. So, it essentially finds the objects you don't want and then compares the values of the objects you do want to the values of the objects you don't want for the argued keys. It then returns all the objects you do want. I could probably write that more succinctly, but w/e.

GraphQL: Querying for a list of object which have relationship to another object

I have set up my schema on GraphCMS and finding graphQL to be very convenient.
I have a workout object and a workoutCategory object. Those two are linked by a many to many relationship.
I'd like to write a query that allows me to get the list of workout which are part of a certain category.
I'm writing the query as follow:
workout(where:{ workoutCategories: { id: "xxxxxxx" } }) {
id
}
graphCMS gives me a syntax error on the workoutCategories which does not make sense to me yet
Field workout categories is not defined by type WorkoutWhereUniqueInput
What do I need to do to be able to achieve my goal?
Thanks in advance
Turns out I need to query on 'workouts' (see the 's' at the end) and not on 'workout'...

RethinkDB: Cannot call `changes` on an eager stream

I have a table of users who each have an array of friends.
A document in it looks something like this:
{
id: "0ab43d81-b883-424a-be56-32f9ff98f7d2",
username: "testUser1234",
friends: [
"04423c56-1890-4028-b38a-cb9aff7112de" ,
"05e4e613-2131-408c-b0ae-a952f3007405" ,
"0395ee53-8ab0-48cc-aa4e-41aad93b8737"
]
}
I want to watch for changes on a user's friends'. A query like this will get me a list of friends:
r.db("Test").table("Users").get("0ab43d81-b883-424a-be56-32f9ff98f7d2")("friends").map(function(id) {
return r.db("Test").table("Users").get(id);
})
But, when I try to throw a .changes() on the end, RethinkDB tells me that it won't work:
RqlRuntimeError: Cannot call `changes` on an eager stream in:
r.db("Test").table("Users").get("0ab43d81-b883-424a-be56-32f9ff98f7d2")("friends").map(function(var_19) { return r.db("Test").table("Users").get(var_19); }).changes()
Is there anyway to get this to work? I am afraid that my only alternative is to subscribe to the friends list (in my app) and update the subscription to the actual friends when it changes:
r.db("Test").table("Users").getAll(friendId1, friendId2 , friendId3, friendId4).changes()
Not the end of the world, but I was really excited about being able to do it entirely in the DB.
Also, can anyone explain what an "eager stream" is? I think it has something to do with lazy vs. immediate evaluation, but I had no idea how to tell what the criteria determines whether a stream is eager or not.
I can get the query working with the following formation, inspired by this post:
r.db("Test").table('Users').getAll(r.args(
r.db('Test').table('Users').get("0ab43d81-b883-424a-be56-32f9ff98f7d2")('friends')
)).changes()
You can attach the .changes before some of the transofrmations.
r.db("Test")
.table("Users")
.get("0ab43d81-b883-424a-be56-32f9ff98f7d2")
.changes()
.getField('new_val')('friends')
.map(function(id) {
return r.db("Test").table("Users").get( id );
})
Basically, every time there is a change, the map function is executed. At the moment, that is the only way to do this type of operations with .changes, but that will change in upcoming versions of RethinkDB.

Meteor: filter data in publish or on client

In Meteor I want to work on the document level when having a Mongo database and according to sources, what I have to watch out for is expensive publications so today my question is:
How would I go about publishing documents with relations, would I follow the relational-type of query where we would find assignment details with an assignment id like this:
Meteor.publish('someName', function () {
var empId = "dj4nfhd56k7bhb3b732fd73fb";
var assignmentData = Assignment.find({ employee_id: empId });
return AssignmentDetails.find({ assignment_id: $in [ assignment ] });
});
or should we rather take an approach like this where we skip the filtering step in the publish and instead publish every assignment_detail and handle that filter on the client:
Meteor.publish('someName', function () {
var empId = "dj4nfhd56k7bhb3b732fd73fb";
var assignmentData = Assignment.find({ employee_id: empId });
var detailData = AssignmentDetails.find({ employee_id: empId });
return [ assignmentData, detailData];
});
I guess this is a question of whether the amount of data being searched trough on the server should be more then or if the amount of data being transferred to the client should be bigger.
Which of these would be most cost effective for the server?
It's a matter of opinion, but if possible I would strongly recommend attaching employee_id to docs in AssignmentDetails, as you have in the second example. You're correct in suggesting that publications are expensive, but much more so if the publication function is more complex than necessary, and you can reduce your pub function to one line if you have employee_id in AssignmentDetails (even where there are many employee_ids for each assignment) by just searching on that. You don't even need to return that field to the client (you can specify the fields to return in your find), so the only incurred overhead would be in database storage (which is v. cheap) and adding it to inserted/updated AssignmentDetails docs (which would be imperceptible). The actual amount of data transferred would be the same as in the first case.
The alternative of just publishing everything might be fine for a small collection, but it really depends on the number of assignments, and it's not going to be at all scalable this way. You need to send the entire collection to the client every time a client connects, which is expensive and time-consuming at both ends if it's more than a MB or so, and there isn't really any way round that overhead when you're talking about a dynamic (i.e. frequently-changing) collection, which I think you are (whereas for largely static collections you can do things with localStorage and poll-and-diff).

Select distinct value from a list in linq to entity

There is a table, it is a poco entity generated by entity framework.
class Log
{
int DoneByEmpId;
string DoneByEmpName
}
I am retrieving a list from the data base. I want distinct values based on donebyempid and order by those values empname.
I have tried lot of ways to do it but it is not working
var lstLogUsers = (context.Logs.GroupBy(logList => logList.DoneByEmpId).Select(item => item.First())).ToList(); // it gives error
this one get all the user.
var lstLogUsers = context.Logs.ToList().OrderBy(logList => logList.DoneByEmpName).Distinct();
Can any one suggest how to achieve this.
Can I just point out that you probably have a problem with your data model here? I would imagine you should just have DoneByEmpId here, and a separate table Employee which has EmpId and Name.
I think this is why you are needing to use Distinct/GroupBy (which doesn't really work for this scenario, as you are finding).
I'm not near a compiler, so i can't test it, but...
Use the other version of Distinct(), the one that takes an IEqualityComparer<TSource> argument, and then use OrderBy().
See here for example.

Resources