Counting 3 Level Model - asp.net-mvc

im trying to figure out how to Count all Items from child to child where a column called "IsVerified" is true. I got the first two childs counted (BlogPost -> Comments(child) -> SubComments(child)) but i cant figure out how to count the third child
The structure of the model is similar to this on
BlogPost -> Comments -> SubComments -> SubSubComments
I cant show you the real models so here is an example:
https://gist.github.com/anonymous/c357bfdd158cc6a392d9
Its all working instead of the third child.
I hope you can help me.
Thanks.

Something like:
// Don't need ToList here, lazy is fine
var blogs = db.BlogPosts.Include("Comments.SubComments.SubSubComments");
var count = blogs.SelectMany(b => b.Comments)
.Where(c => c.IsVerified)
.SelectMany(c => c.SubComments)
.Where(sc => sc.IsVerifier)
.Count();
will get the count of verified sub-comments in verified sub-comments.
And because I've not used ToList on the initial expression this should all be converted to SQL and executed on the server (details of the SQL will depend on the details of the model, for example whether relationships are required or not).

Related

Returning multi value in dynamic query using neo4j client

Following the question I asked: Build a dynamic query using neo4j client
I got an answer about how can I return value dynamically using string only.
When I'm trying to use the syntax to return multi values from the query it failed,
I tried the following query:
var resQuery2 = WebApiConfig.GraphClient.Cypher
.Match("(movie:Movie {title:{title}})")
.OptionalMatch("(movie)<-[r]-(person:Person)")
.WithParam("title", title)
.Return(() => Return.As<string>("movie, collect([person.name, head(split(lower(type(r)), '_')), r.roles])"));
I'm getting the following error:
The deserializer is running in single column mode, but the response
included multiple columns which indicates a projection instead. If
using the fluent Cypher interface, use the overload of Return that
takes a lambda or object instead of single string. (The overload with
a single string is for an identity, not raw query text: we can't map
the columns back out if you just supply raw query text.)
Is it possible to return multiple nodes using only strings?
We can't get an output like in the question you asked previously - this is due to the fact that you are asking for a Node (the movie) and a Collection of strings (the collect) and they have no common properties, or even styles of property.
Firstly, let's look at the painful way to do this:
var q = gc.Cypher
.Match("(movie:Movie)")
.OptionalMatch("(movie)<-[r]-(person:Person)")
.Return(() => Return.As<string>("{movie:movie, roles:collect([person.name, head(split(lower(type(r)), '_')), r.roles])}"));
var results = q.Results;
Here we take the query items (movie, r, person) and create a type with them the {} around the results, and cast that to a string.
This will give you a horrible string with the Node data around the movie and then a collection of the roles:
foreach (var m in results)
{
//This is going to be painful to navigate/use
dynamic d = JsonConvert.DeserializeObject<dynamic>(m);
Console.WriteLine(d.movie);
Console.WriteLine(d.roles);
}
You'd be a lot better off doing something like:
var q = gc.Cypher
.Match("(movie:Movie)")
.OptionalMatch("(movie)<-[r]-(person:Person)")
.Return(() => new
{
Movie = Return.As<Node<string>>("movie"),
Roles = Return.As<IEnumerable<string>>("collect([person.name, head(split(lower(type(r)), '_')), r.roles])")
});
var res = q.Results;
You could either JsonConvert.DeserializeObject<dynamic>() the Movie node, at your leisure, or write a strongly typed class.
In terms of a 'dynamic' object, I don't know how you were wanting to interact with the collect part of the return statement, if this doesn't help, you might need to update the question to show a usage expectation.

How do I remove rows of an RDD whose key is not in another RDD?

Let's say I have a PairRDD, students (id, name). I would like to only keep rows where id is in another RDD, activeStudents (id).
The solution I have is to create a PairDD from activeStudents, (id, id), and the do a join with students.
Is there a more elegant way of doing this?
Thats a pretty good solution to start with. If active students is small enough you could collect the ids as a map and then filter with the id presence (this avoids having to a do a shuffle).
Much like you thought, you can do an outer join if both RDDs contain keys and values.
val students: RDD[(Long, String)]
val activeStudents: RDD[Long]
val activeMap: RDD[(Long, Unit)] = activeStudents.map(_ -> ())
val activeWithName: RDD[(Long, String)] =
students.leftOuterJoin(activeMap).flatMapValues {
case (name, Some(())) => Some(name)
case (name, None) => None
}
If you don't have to join those two data sets then you should definitely avoid it.
I had a similar problem recently and I successfully solved it using a broadcasted Set, which I used in UDF to check whether each RDD row (rather value from one of its columns) is in that Set. That UDF is than used as the basis for the filter transformation.
More here: whats-the-most-efficient-way-to-filter-a-dataframe.
Hope this helps. Ask if it's not clear.

Breeze predicate on multiple levels of children

I'm a beginner in Breeze and have a problem with the following situation
I have the following model. A Person entity, can have multiple Projects assigned. A project can have multiple Tasks. And each Task has a Priority. I would like to get all the Persons which have at least one Project which has at least one Task with a Priority code 'High'.
I found I can use the 'any' or 'some' for working with 2nd level children.
var p1 = new breeze.Predicate.create('projects', 'some', 'client.code', 'Equals', 'ABC');
The above correctly returns Persons with Projects for Clients with code ABC. But in my case I would have to apply the 'any' one level deep, also to Tasks and I can't find the correct way of doing it.
Thanks for any help
You can nest multiple any/all using that syntax:
var query = breeze.EntityQuery.from('persons')
var p = new breeze.Predicate('projects', 'any', new breeze.Predicate('tasks','any','priority','>',1));
query = query.where(p);
You'll have to change the MaxAnyAllExpressionDepth property of your controller to allow multiple any level:
[BreezeNHController(MaxAnyAllExpressionDepth = 5)]

RoR scope on each array-object

i am pretty new to RoR so this might be a newbie question but i couldn't find an answer to it and solve the problem.
I need to check every single element from a dynamic array (which is created by a HABTM connection over a join table) for a condition.
Right now i have something like this:
scope :filter, lambda { |devicefilter, testtypefilter|
{
testtypefilter.each { |testtype|
:include => :tests,
:conditions => ['(tests.device != ? OR tests.device IS ?) AND ? NOT IN tests.testtypes', devicefilter, nil, testtype]
}
}
}
This shows me a syntax error.
But i think even if i manage to get it working this way it would not perform the sql query correctly since ts and tts is connected by HABTM, so the actualy value in the table is NULL and i would have to create another join in that query.
I have really no clue how to solve this.
Any hints would be helpful.
Thanks,
Niko
Edit:
My Controller looks like this
if params[:d] == nil or params[:t] == nil
#users = User.all
else
#users = User.filter(params[:d], params[:t])
end
:d is a fixed value which is comming from a select_tag
:t is an array which is comming from a bunch of dynamic checkboxes
the values are all fine and being passed correctly to the Model. So the view or controller shouldn't be the problem.
Edit2:
Since it looks a bit unclear, here is the current situation:
There is a form which consists of a Select-Box and a bunch of Checkboxes.
The Select-Box is getting its values from the table "devices" and after the form is submitted it passes the selected value to the controller as the param :d.
The Checkboxes are a list from all entries of the table "testtypes" and after the form is submitted it passes an array of all checked testtype_ids from the table to the controller as the param :t. (works correctly)
Now there is another table "tests" which has a HABTM connection to all entries in devices and testtypes, so i can gather special connections from 1 device and and multiple testtypes together in a single entry.
Now in the table "users" there is a column "tests" which refers to the table "tests" in a HABTM connection so 1 user can have (participated in) multiple tests (which can have multiple testtypes).
So after the form is submitted the values :d and :t should be used for a sql query to filter all users by tests (while tests are dependant by devices and testtypes). So all users should by checked in the column tests by the values of the referring tests in devices (:d) and testtypes (:t[]).
But since testtypes (:t[]) is being passed as an array i have to check somehow every single element of that array with a sql request. Or is there a way to check for the whole array?
Example:
There are 3 Devices: (dynamic table)
A01
A02
A03
There are 3 Testtypes: (dynamic table)
TT01
TT02
TT03
There are 4 Tests: (dynamic table with HABTM devices and testtypes)
T1 = A01 - TT01/TT03
T2 = A01 - TT03
T3 = A02 - TT02/TT03
T4 = A03 - TT01/TT02/TT03
There are 5 Users: (dynamic table with HABTM tests)
U1 = ... T1 ...
U2 = ... T2/T4 ...
U3 = ... T3/T4 ...
U4 = ... T1/T2/T3 ...
U5 = ... T3/T4 ...
Now the Form will look like:
Device: Select-Box={A01/A02/A03}
Testtypes: Checkboxes={TT01/TT02/TT03}
If i select now A01, check TT01+TT02 and submit the query should return every single User who has not participated in the following Tests:
A01 - TT01
A01 - TT02
So at last i get a list of users that i could use for the test A01 - TT01+TT03, since there are no conflicts.
So the query would return every user who has not participated in T1, since that is the only conflict.
So the userlist would look like:
U2
U3
U5
Can someone help me with this?
Noone got an idea? :'(
Sounds like you want something like
scope :filter, lambda {|df| includes(:ts).where("foo_id in (?)", df)
which will allow you to do
SomeModel.filter([23,24])
And that that array would be passed into the lambda for you to use in the conditions.

Subsonic 3 getpaged filter question

I am sure this is a stupid question, but how would I get a pagedlist of filtered items?
Here is how I ended up doing it:
PagedList<Company> company = Company.GetPaged(1, 10);
var list = Company.Find(x => x.CompanyName.ToLower().Contains(query.ToLower()));
company .Clear();
foreach (var x in list)
company .Add(x);
return View(company );
In other words I want to do a find on the table, and return a paged list of the results.
Thanks!
There is a fantastic example of this in NerdDinner.
If you have trouble finding it then let me know and I'll post the code for ya.
Actually it's fairly easy to get the paged list and you said the answer in your question
In other words I want to do a find on
the table, and return a paged list of
the results.
Create your LINQ query (do a find on the table)
New up a SubSonic.Schema.PagedList(of T) (return a paged list)
For example:
var list = Company.Find(x => x.CompanyName.ToLower().Contains(query.ToLower()));
var paged = new SubSonic.Schema.PagedList<Company>(list,1,10)

Resources