Some basics of compartment search - hl7-fhir

I am new to FHIR, and am unable to understand the concept of compartment search.I have read compartment is a group of similar resources, but when we do compartment search we provide the following path:
/[compartment]/[id]/?[parameters]
'/[compartment]/[id]/[type]?[parameters]'
'/[compartment]/id/condition '
Can anyone please give reasons why we are using ID as a parameter in each request, and also please give one one example of each request.

You can do this:
/Patient/1/$everything, however that's not really a compartment based search. It's a resource-instance specific operation that depends on the existence of compartments to function - it says "find me everything in this patient's compartment"
For compartment based search, you'll either have this:
/[compartment]/[id]/[type] (e.g. /Patient/1/Condition) if you want all records of the specified type within the compartment
or this
/[compartment]/[id]/[type]?[parameters] (e.g. /Patient/1/Condition?category=diagnosis) if you want to further filter the records.
id isn't a parameter, it's identify the compartment. In the example above, you're saying "I want the conditions that belong to patient 1". There's no difference between the following two queries:
/Patient/1/Condition
/Condition?patient=1
The only reason we support compartments is that some systems like to do logic or security based on URL. Nesting queries beneath a selected Patient or Practitioner, etc. lets them do that.

Related

Distributed GraphQL in microservices

I'm trying to write microservices in Java. I've implemented GraphQL endpoints using graphql-spring-boot-starter.
Now I have a problem how to make it efficient.
Datamodel is like a tree and I need to query for data from multiple services at once. The problem is how to filter for a member of collection, something like CONTAINS in database, but data is not in separate table, but separate microservice. Maybe the problem is that domain is not correctly splitted between services?
Let's make an example: I have 3 microservices: users, libriaries, books. Every library have collection of users and books (just list of identifiers, like foreign keys). Every book has a name and genre. Every library have lists of books borrowed by user (identifiers too).
Question 1 - should library hosts list of books and users (just identifiers, like foreign keys)? Is it correct approach?
Question 2 - I want to find libraries in which specified users (by surname) have borrowed books of specified genre. Going from top I need to first find libraries containing users. Not easy, as we have names in different service. We need to query first for users, gathers their identifiers, and now we are able to query for libraries. But it isn't all. Now we need to find books for every user and check genres - in different service. And it's not all. I want to have everything presented in nice way, so whole output should be sorted and paged. It force me to collect all data from all services, then page and sort it, which of course will not be efficient.
Please don't concentrate on this example, I'm looking how to solve general approach, not this one example. I've tried to use Datafetchers but it's troublesome and there are not good examples of calling Graphql-to-GraphQL. Most examples covers calling REST endpoints etc.

GraphQL viewer-contextual queries on the top-level or within the viewer type?

When building the query and type graph structure in a GraphQL API, where would you put highly contextual queries that only apply to the viewer?
On the top-level (query.friendRequests)
This would remove noise in the User entity and only keep queries in there that are queryable for all users. Not just the viewing user.
It would add much more top-level queries with a risk of them becoming specialists in specific things which is not really thinking-in-a-graph and model-data-around-business-logic ideas.
On the viewer entity (query.viewer.friendRequests)
From a data perspective, this makes more sense to put it underneath the viewer entity (which is a User type). friend requests always belong to a parent object which is always a user.
Other Examples
Dashboard widgets
User notifications
Action items / TODO items / Task lists
Messages
Counters and badges
What are you guys' thoughts on this? What would be a good best-practice to follow for viewing user contextual queries that don't apply to other user entities in an API implementation?
We have always put it under a specific field in Query. First we started with a me query that would return a user. But this did not turn out very practical because the user type got very big and also most fields did not need the whole user object but only the user's ID. In your example we would have done two queries
SELECT * FROM account WHERE id = $id
SELECT * FROM friend_request WHERE account_id = $id
Unless we would query a trivial field on the me query the first query was completely wasted.
Then we got inspired a bit this thread and especially this answer from Lee Byron
Viewer is what we used everywhere at FB, so it’s stuck with me. Also, a Viewer is not a User, it’s an Auth session - which references a User. So there’s a useful distinction of terms.
Now we have a viewer query that returns a Viewer object. This object then has a field user to query the actual user object. This also might or might not help solving the problem around private and public fields on your user object.

How can I search users by id

Correct me if I'm wrong but it appears that the admin-sdks's Users>list operation doesnt support searching users by ID (According to the docs here).
For example I use the Members api to get all the members of a given group. It returns a list or User Ids.
The only way to fetch data about those users is to call the get operation for each user. Seems pretty inefficient to me.
How come this functionality is not implemented (or perhaps I'm missing something)?
Search feature means you have a pattern and you want the list of all entities which relate to given pattern. It assumes you don't have the unique id of the entity you need. The output of search feature is the list of unique ids with optional additional minimal information which matches to search pattern. To get full information of the individual entity, you need to use unique id and use get information feature.
However, if you already have the unique id, then you don't need the search function. Directly use get information feature.
So google has provided sufficient functionality. If you already have userid, why using search call, use retrieve user call directly.

XPages: can i filter a view to show only entries that belong to a group?

i have a view in an xpage with some entries (lets say clients). I have an acl group of persons (clients) that contains some of the clients of the view. Now i want to use the search attribute of the view to show only entries that belong to the group.
I already use search attribute to select users by name e.g:
FIELD Name Contains "Chuck Norris"
Is there any similar query? (maybe using #isMember on the field....?)
UPDATE: i will have the group entries (client names) into a text list in a document too. so can i filter the "name" field of the view based on the values of a text list?
Perhaps using a reader field is a good idea. You're talking about restricting document access to a group of Domino users - that's exactly what reader fields are for.
For example, make your text list field containing client names into a reader field like this:
var item = document1.getFirstItem("myfield");
item.setReaders(true);
document1.save();
myfield needs to contain canonical names (CN=firstname lastname/O=organisation).
Using reader fields, you don't need to do any view filtering at all, it happens automatically. If you have really many documents (say, half a million or so), it could slow down things, otherwise, it's a nice approach.
When you want to restrict displaying documents only in one certain view reader fields are no solution, though. In that case, you need to do the view filtering yourself as you tried.
If you want to filter only for ONE certain client, then using a categorized view is the way to go. You can give the view panel the name of one client as category filter then.
If you want to filter for multiple clients, you need to do it based on fulltext search, just as you already tried. In that case, make sure you're working with Domino 9. Previous Domino versions don't apply the view sorting order to a fulltext search result, which means you have to search it manually using custom javascript or so, which is complicated.
Or, as Frantisek suggested, write a scheduled agent which puts documents in folders depending on their clients - but depending on the number of clients you want to filter the view for this may lead to many folders, which may lead to other problems. Furthermore, you need to make sure to remove folders when they are not needed anymore, and you have a lag until new documents appear in a folder.
So in a nutshell, if you want to do an application wide restriction based on client names, use reader fields.
If you want to restrict for one client name at a time, use categories.
Otherwise, use fulltext search with Domino 9.

BigTable query with IN operator to get all user group keys

I have little problem with permissions in my future social application.
Platform will nonrel db (Google's BigTable).
In my application each user has groups (for example: friends, collaborators, family...). In group has some friends (like in Facebook). And can publish some content (news, short text, ...) only for this group.
If I have user in my group it is my friend. Like in Facebook, but more groups.
My idea is, that each user can see (on himself "feed") all last content of all friends in one page (like as Facebook's Top news).
But I have problems with creating simple query.
For example:
SELECT * FROM News WHERE group_key IN [list_of_groups_where_i_am]
This works good, but there are sub-queries and limit of list is 30 items.
Other way is strong caching of content.
Does anybody have some idea? Or any study material, example...
With a requirement like this you can optimize for either read or write, but usually not both. You have the write optimized version - just write a record with the right group key but have a complex query to get content for all the groups.
The read optimized version would be to write the content (or just its id) to a feed for each user, which makes the read query very simple.

Resources