Typeorm how to find entities that does not have relation? - typeorm

Inside typeorm 0.3 we are able to find users who have posts by the next code:
userRepo.find({
where: {
posts: {
post_id: Not(IsNull())
}
},
relations: ['posts']
})
Does anyone know how to find users who have no posts at all (without using raw code)?

Related

RUBY Grouping data by parsed REST JSON result property

First of all, I am very new to Ruby so go easy on me! I have the parsed JSON in my sourceHash variable and I am trying to group data by the "displayName" property. The JSON format is something like this (I've simplified it without changing the structure):
{
"results": [
{
"id": "12345",
"title": "my blog post",
"history": {
"createdOn": "2017-09-18 15:38:26",
"createdBy": {
"userName": "myUserName",
"displayName": "Michael W."
}
}
},
{ ... same stuff for some other blog post ... },
{ ... same stuff for some other blog post ... },
{ ... same stuff for some other blog post ... }
]
}
Basically, there are two things I want to do.
Imagine this list as "list of blog posts including the author data" of them.
Find the person who posted the most amount of entries
Get the top 10 bloggers, ordered by their blog post count, descending
So the first would look something like this:
Michael W. (51 posts)
However, the second one would look like this:
Michael Wayne (51 posts)
Emilia Clarke (36 posts)
Charlize Theron (19 posts)
Scarlett Johansson (7 posts)
I've played around these queries, trying to merge my LINQ logic into this, but I failed... (I'm a Ruby noob so be easy!)
sourceHash = #mainData["results"]
hashSetPrimary = sourceHash.group_by{|h| h['history']['createdBy']['displayName']}
return hashSetPrimary
So long story short, I am trying to write to separate queries that would group the data by those criteria, any help is appreciated as I can't find any proper way to do it.
Firstly, you need to look at your hash syntax. When you define a hash using h = { "foo": "bar" }, the key is not actually a string, but rather a symbol. Therefore accessing h["foo"] is not going to work (it will return nil); you have to access it as h[:foo].
So addressing that, this does what you need:
sourceHash = #mainData[:results]
hashSetPrimary = sourceHash.group_by{ |h| h.dig(:history, :createdBy, :displayName) }
.map { |k, v| [k, v.count] }
.sort_by(&:last)
return hashSetPrimary
Hash#dig requires Ruby 2.3+. If you are running on a lower version, you can do something like this instead of dig:
h[:history] && h[:history][:createdBy] && h[:history][:createdBy][:displayName]

Syntax for submitting a mutation to a graphql-relay mutationWithClientMutationId

I defined a GraphQL Mutation using graphql-relay but am having issues figuring out how to submit a mutation to it.
Here is the relevant schema:
const userType = new GraphQLObjectType({
name: 'User',
description: 'user',
fields: () => ({
id: {
type: new GraphQLNonNull(GraphQLString),
description: 'The UUID for the user.',
resolve(user) {
return user.uuid;
},
},
})
});
const registerUser = mutationWithClientMutationId({
name: 'registerUser',
inputFields: {
},
outputFields: {
user: {
type: userType,
resolve: (payload) => {
models.user.findById(payload.userId);
}
},
},
mutateAndGetPayload: (args) => {
var newUser = models.user.build().save();
return {
userId: newUser.id,
};
}
});
const rootMutation = new GraphQLObjectType({
name: 'RootMutationType',
fields: {
registerUser: registerUser,
},
});
const schema = new GraphQLSchema({
query: rootQuery,
mutation: rootMutation,
});
What should an HTTP call look like to register a new user and get back the userId?
Thanks!
I want to point out that I see that you're saying that your mutation requires no parameters - how does it know what the new user's details are? You'll probably need some parameters on that mutation, eventually. They would be available to your mutateAndGetPayload on that first function parameter. (I'm not saying every mutation needs parameters, but this one probably does)
If you're using Relay, there is some pretty good information on the official document as to how to use your mutations from Relay. Particularly down at the bottom where it shows the various mutator configs. If you're using connections, you may want to use RANGE_ADD to add this new account to the Relay store manually, otherwise if you'd like to perform a more broad refetch you can use FIELDS_CHANGE. You said you need the new user id after the mutation finishes. If you're using Relay, you may need to look into REQUIRED_CHILDREN to specify that regardless of the computed query that Relay will build, you always want that id to be queried.
The output of your mutation is a userType, so you'd be able to access it with a fragment on the payload type, which would probably be RegisterUserPayload, that might look something like ...
fragment on RegisterUserPayload {
user {
id
}
}
Now, that's assuming you're using Relay. If you'd like to try this out manually via GraphiQL, then you can use the examples of how to do mutations through there on the GraphQL Mutation docs. There's a direct example of how you'd query your mutation.
Last, since you asked how to do this at a low level of issuing the HTTP request yourself, for that you can look at express-graphql documentation, which explains how to query it.
I figured out a mutation format that worked:
mutation RootMutationType {
registerUser(input:{clientMutationId:"123"}){
clientMutationId, user { id }
}
}

Firebase - User Based Rule Access On Another Path

I'm looking to allow read access to a device list in firebase only if a user has this device id listed under their account.
As recommended by Anant in his answer found here: Security Rules - lists of data that can be read?
I implemented this firebase data structure:
{
devices: {
111: {status: 10},
222: {status: 5}
},
users: {
aaa: {
name: 'Jim',
devices: {
111: {name: 'Test Device'}
}
}
bbb: {
name: 'Jane',
devices: {
111: {name: 'Test Device'},
222: {name: 'New Device'}
}
}
}
}
To clarify the outputs, User "aaa" named Jim should only be able to read device id "111" from the device list and get it's children elements. User "bbb" named Jane can see both devices "111" and "222" and their children elements
So I implemented several rules trials and ended with the following:
{
"rules": {
"users":{
"$user_id":{
".read": "auth.uid == $user_id",
"devices": {
"$devices_id":{
".read":true
}
}
}
},
"devices":{
"$devices_id":{
".read": "root.child('users').child(auth.uid).child('devices').hasChild('$devices_id')",
".write": false
}
}
}
}
When reading device data this rule should look at the /root/users//devices/$devices_id and see if that device_id exists under the user making the request. Then allow read access to that record. According to the post linked above this should be possible, but the post does not express what permissions should be set for the main list of "conversations" (devices in my case)...Anant only says "Make sure to set the permissions on the top-level conversations list appropriately". Can someone clarify how to do this?
I only get permission denied for these requests under the rules above. I have also tried:
"root.child('users').child(auth.uid).child('devices').child('$devices_id').exists()"
And this does not work either...
Any guidance on this process would be greatly appreciated. I am also open to other data structures and rules structures that make this happen. It is a fresh project and very modifiable at this stage.
Thanks!
Thanks to #Kato! The implementation above is correct except for the string literal surrounding $device_id.
Changing
.hasChild('$devices_id')
To
.hasChild($devices_id)
Fixed the problem and allowed only the assigned devices under a user to be readable from the top level devices structure.

Returning a custom field where value depends on the query in elasticsearch

I have some data like so in elasticsearch:
account (http://localhost:9200/myapp/account/1)
========
name
state
groups //groups is an array containing objects like so {id: 1, starred: true}
//the id is the id of the group type
email (http://localhost:9200/myapp/email/1?parent=1)
========
email
primary //just a boolean to denote whether this email is primary or not
group
========
name
description
emails are children of account.
Based on imotov's excellent answer, I am able to run a search on account.name and email.email and return ALL accounts where the searched prefix matches the above 2 fields:
{
"query": {
"bool": {
"must": [
{
"term": {
"statuses": "active"
}
}
],
"should": [
{
"prefix": {
"name": "a"
}
},
{
"has_child": {
"type": "email",
"query": {
"prefix": {
"email": "a"
}
}
}
}
],
"minimum_number_should_match" : 1
}
}
}
What I would like to do now is to return 2 custom fields for each result:
For each result return a field called email, if the search was matched on the email type (which is a child of account), return that email, otherwise return the primary email linked to the account, if none, null can be returned.
For each result return a field called group. The value of the field should contain the name of the starred group whose id is stored in the groups array. Essentially: Find group.id where group.starred is true in each account.groups, then return the matching group.name from the group type base on the id we found.
I have been looking at script fields, but I am not sure if it is able to return fields for each hit. I am also not sure if the above is actually accomplishable in ES.
Could someone provide some pointers as to whether this is possible and how to get started?
Currently, there is simply no way to get to access the data in a has_child or nested clause.
The only solution is to get some data, make some decisions on the client and then get more data.
Here's what I did to achieve it:
Run the query above and get back the data.
To deal with showing the match emails or the primary email (run on the email type):
{"query":
{"bool":{
"should":{
{
"prefix":{
"email" : "the query"
}
},
{
"terms":{
"_parent" : ["list", "of", "account", "ids"]
}
}
}
}
}
}
Base on the above query, we can get any email addresses that were matched by the search term. Remember to set the fields in the above query to include _parent.
We can then use array_diff() or a similiar function in languages other than PHP to diff the parent ids from above and and original query. This should then give us a list of accounts where no email was matched. Simply then send another request to get the primary emails for those accounts.
For the groups, send a query to type account and:
Constrain _id to the list of account ids.
Constrain group.starred to true.
This should get you a list of starred groups. To get more information (name etc), send a query to type group and:
Constrain _id to the group ids above.
Finally, do some client side processing to put it together so that it is easier for the next part of your program to use.

Fusion Tables query for grouped data timing out

Using the guidelines here I have successfully queried a simple fusion table for some basic data with the following code:
google.load('visualization', '1', { packages: ['corechart'] });
function drawVisualization() {
google.visualization.drawChart({
containerId: 'visualization',
dataSourceUrl: 'http://www.google.com/fusiontables/gvizdata?tq=',
query: 'SELECT sector, revenue FROM 2961086',
chartType: 'LineChart',
options: {
title: 'Net Revenue by Sector',
vAxis: {
title: 'Revenue'
},
hAxis: {
title: 'Sector'
}
}
});
}
google.setOnLoadCallback(drawVisualization);
A problem arises when I attempt to aggregate the data by sector. I've tried the following
query: 'SELECT sector, revenue FROM 2961086 GROUP BY sector'
with no luck, the request eventually times out.
I threw together two pages demonstrating the issue.
I've also tried queries with various other parameters that work with no trouble whatsoever. Am I missing something?
I'm not a google.visualization user, just a fusion-table user but I would guess that you need an aggregate function in your query: SELECT sector, sum(revenue) from ... GROUP BY sector
Eric

Resources