Nhibernate partial eager load of child collection - vb.net

If I have a parent object (Parent) which has a List(Of Child) objects as a many-one relationship. Is it possible to return a Parent with a subset of it's child objects (eagerly loaded)? I am using VB and Criteria.
e.g. If Parent 1 has 50 children (20 type X 30 type Y) and I want to return the Parent with a collection containing only type X.
I only want a collection with a size of 20 with it's eagerly loaded children?
Thanks

HQL query. The fetch keyword will initialize the children along with the parent.
from parent left join fetch parent.Children as child where child.type = X

Related

neo4j Parent child relationship of n-levels

I have Parent child relationships of say 10-11 levels like shown below and I need to create a relationship between them as parent child
data format
id,parentid
1,0
2,1
3,2
4,3
5,4
6,5
what I tried so far?
I have used the below code to relate them as parent child
LOAD CSV WITH HEADERS FROM 'file:///parent_child.csv' AS line
MERGE (thisThingHere:employee {id: line.id })
MERGE (parent:Element { id: line.parentid })
MERGE (thisThingHere)-[:PARENT]->(parent)
the result of above code is creating parent child relations but they are relating up to just one level, like shown in the below image (available as a link), I need a way to relate them and display it like a tree eg. 3 is a parent of 4 and 2 is a grand parent of 4 and 1 is great grand parent of 1, can anyone please help me on how can I achieve it?
result of my query above
You need to use the same node label for both parent and child node to construct a tree
LOAD CSV WITH HEADERS FROM 'file:///parent_child.csv'
AS line
MERGE (thisThingHere:Element {id: line.id })
MERGE (parent:Element { id: line.parentid })
MERGE (thisThingHere)-[:PARENT]->(parent)

Why are all my SQL queries being duplicated 4 times for Django using "Prefetch_related" for nested MPTT children?

I have a Child MPTT model that has a ForeignKey to itself:
class Child(MPTTModel):
title = models.CharField(max_length=255)
parent = TreeForeignKey(
"self", on_delete=models.CASCADE, null=True, blank=True, related_name="children"
)
I have a recursive Serializer as I want to show all levels of children for any given Child:
class ChildrenSerializer(serializers.HyperlinkedModelSerializer):
url = HyperlinkedIdentityField(
view_name="app:children-detail", lookup_field="pk"
)
class Meta:
model = Child
fields = ("url", "title", "children")
def get_fields(self):
fields = super(ChildrenSerializer, self).get_fields()
fields["children"] = ChildrenSerializer(many=True)
return fields
I am trying to reduce the number of duplicate/similar queries made when accessing a Child's DetailView.
The view below works for a depth of 2 - however, the "depth" is not always known or static.
class ChildrenDetailView(generics.RetrieveUpdateDestroyAPIView):
queryset = Child.objects.prefetch_related(
"children",
"children__children",
# A depth of 3 will additionally require "children__children__children",
# A depth of 4 will additionally require "children__children__children__children",
# etc.
)
serializer_class = ChildrenSerializer
lookup_field = "pk"
Note: If I don't use prefetch_related and simply set the queryset as Child.objects.all(), every SQL query is duplicated four times... which I have no idea why.
How do I leverage a Child's depth (i.e. the Child's MPTT level field) to optimize prefetching? Should I be overwriting the view's get_object and/or retrieve?
Does it even matter if I add a ridiculous number of depths to the prefetch? E.g. children__children__children__children__children__children__children__children? It doesn't seem to increase the number of queries for Children objects that don't require that level of depth.
Edit:
Hm, not sure why but when I try to serialize any Child's top parent (i.e. MPTT's get_root), it duplicates the SQL query four times???
class Child(MPTTModel):
...
#property
def top_parent(self):
return self.get_root()
class ChildrenSerializer(serializers.HyperlinkedModelSerializer):
...
top_parent = ParentSerializer()
fields = ("url", "title", "children", "top_parent")
Edit 2
Adding an arbitrary SerializerMethodField confirms it's being queried four times... for some reason? e.g.
class ChildrenSerializer(serializers.HyperlinkedModelSerializer):
...
foo = serializers.SerializerMethodField()
def get_foo(self, obj):
print("bar")
return obj.get_root().title
This will print "bar" four times. The SQL query is also repeated four times according to django-debug-toolbar:
SELECT ••• FROM "app_child" WHERE ("app_child"."parent_id" IS NULL AND "app_child"."tree_id" = '7') LIMIT 21
4 similar queries. Duplicated 4 times.
Are you using DRF's browsable API? It initializes serializer 3 more times for HTML forms, in rest_framework.renderers.BrowsableAPIRenderer.get_context.
If you do the same request with, say, Postman, "bar" should get printed only once.

Lambda Statement that selects all child that match criteria

I have a data structure as listed below. How do I get the children of the children that meet the criteria?
I have a list of Adults that contain a list of children.
AdultJoe
ChildJoe Age 12
ChildJane Age 10
AdultFrancis
ChildTom Age 12
ChildTony Age 10
Using the above data structure how do I get all of the child that are age 12?
This is what I've tried and it's not doing what I need.
Adults.Where(Function(adult) adult.Children.Any(Function(child) child.age= 12))
To "flatten" an IEnumerable of IEnumerables, use SelectMany:
Dim children = Adults.SelectMany(Function(a) a.Children).Where(Function(c) c.Age = 12)
This is implicit in the LINQ syntax:
Dim children = from adult in Adults
from child in adult.Children
where child.Age = 12
select child
You didn't describe your classes, but assuming that the adults have a Children property, you could use something like this:
Dim twelveYearOlds = adults.SelectMany(
Function(adult) adult.Children
).Where(
Function(child) child.Age = 12
)
The SelectMany gives you a list of all the children of all the adults, and the where filters that list to the 12-year-olds.

How to limit subnodes from each nodes Neo4j Cypher

I am new to Neo4j,I have the following situation
In the above diagram represented a node with label user with sub-nodes having label shops. Each of these sub-nodes have sub-nodes with label items. Each node items has attribute size and the items node is in descending order by size attribute for each node shops as represented in the figure.
Question
I want to get two items node whose size is less than or equal to 17 from each shops .
How to do that? I tried, but its not working the way I need
Here is what I have tried
match (a:user{id:20000})-[:follows]-(b:shops)
with b
match (b)-[:next*]->(c:items)
where c.size<=17
return b
limit 2
Note- These shops node can have thousands of items nodes. So how to find the desired nodes without traversing all thousands of items nodes.
Please help , thanks in advance.
Right now Cypher does not handle this case well enough, I would probably do a java based unmanaged extension for this.
It would look like this:
public List<Node> findItems(Node shop, int size, int count) {
List<Node> results=new ArrayList<>(count);
Node item = shop.getSingleRelationship(OUTGOING, "next").getEndNode();
while (item.getProperty("size") > size && results.size() < count) {
if (item.getProperty("size") <= size) result.add(item);
item = item.getSingleRelationship(OUTGOING, "next").getEndNode();
}
return result;
}
List<Node> results=new ArrayList<>(count*10);
for (Relationship rel = user.getRelationships(OUTGOING,"follows")) {
Node shop = rel.getEndNode();
results.addAll(findItems(shop,size,count));
}
You can avoid having to traverse all items of each shop by grouping them according to size. In this approach, your graph looks like this
(:User)-[:follows]-(:Shop)-[:sells]-(:Category {size: 17})-[:next]-(:Item)
You could then find two items per shop using
match (a:User {id: 20000})-[:follows]-(s:Shop)-[:sells]-(c:Category)
where c.size <= 17
with *
match p = (c)-[:next*0..2]-()
with s, collect(tail(nodes(p))) AS allCatItems
return s, reduce(shopItems=allCatItems[..0], catItems in allCatItems | shopItems + catItems)[..2]
shopItems=allCatItems[..0] is a workaround for a type checking problem, this essentially initializes shopItems to be an empty Collection of nodes.

nHibernate - IStatelessSession and FetchMany returning multiple parent records

I have the following linq statement:
var query = from p in session.Query<Parent>().FetchMany(x => x.Children)
select p;
I end up with a new Parent object for each Child in Children. So if i had 5 Children, I would get 5 separate, but identical, Parent objects back. Is this the intended behavior? If i use ISession, I get 1 Parent as expected.
This is expected, because Stateless Sessions do not track objects; therefore each row results in a new instance.
Have you tried to do a Distinct call on the query?
var results = query.Distinct();