Umbraco AncestorOrSelf(int) - umbraco5

I am using Umbraco CMS and facing a problem in accessing the Contact us page using the AncestorOrSelf method.
I have tried to explain it by example.
- Content
-- Home (level = 1)
-- About Us (level = 2)
-- Contact Us (level = 2)
-- News Area (level = 2)
-- News Item 1 (level = 3)
-- News Item 2 (level = 3)
-- Other Node (level = 1)
By using Model.Content.AncestorOrSelf(1) I am getting the Other Node
(level = 1 as in example).
How could I get the contact us page which is under Home level?

AncestorOrSelf(level) will traverse upwards through the ancestors of the node you are querying from. It will stop at the first node it finds that matches the level specified in the parameter.
In your case that would mean that doing a AncestorOrSelf query from any of the level 2 or level 3 nodes would traverse upwards until it reaches the Home node. It should never reach the Other Node unless you are doing it from a child/descendant node below the Other Node.
If this is not the case - what is the current page when you are executing this query?

Related

Get Lowest level in tree created with hierarchyId that respect some conditions

I have created a hierarchy table in my SQL Server. I have a column hierarchyId. Each level of hierarchy represent a geographical/political level of a country:
Countries
Regions
Provinces
For each row I can fill some boundaries or not. To simplify I replace in the example the geometry column with a bit column.
I need to get lowest level that has boundaries filled. If at least one child has boundaries, surely also parent has boundaries.
I make an example:
For example, I have that tree. In my query I should get green and red areas. In this moment I get only green areas.. so, I should get:
Valle d'aosta because is the lowest level and it has boundaries (and that is OK);
Milano and Brescia because they are the lowest level with boundaries. I should not get Bergamo because it has no boundaries, but I should get Lombardia instead of Bergamo;
Italy because both Piemonte and Torino have no boundaries;
Lazio because Roma has no boundaries.
My query is partially correct.. I get all lowest levels. But I do not get the minimum high level that respect my condition..
I share a link with the example: http://sqlfiddle.com/#!18/878577/1
Here also the query you can see in sql fiddler:
select * from country_subdivisions cs
where IsoCode IN(
select cs.IsoCode
from parent p
where cs.Level.IsDescendantOf(p.Level) = 1
and p.CountryISOAlpha2Code = cs.CountryISOAlpha2Code
-- and (cs.Level.GetLevel() = p.Level.GetLevel() + 1 or cs.Level.GetLevel() = p.Level.GetLevel())
and cs.Level.GetLevel() = (SELECT MAX(leaf.Level.GetLevel()) FROM country_subdivisions leaf WHERE leaf.Level.IsDescendantOf(cs.Level) = 1 and leaf.HasBoundaries = 1)
)
As you can see I correctly get the green areas but not the red one.
Any Idea? Do I have been clear?
Thank you
I think the logic is summarized as follows:
Return a parent when:
That parent has boundaries, and
Either:
it has no children, or
it has has at least one child that has no boundaries.
This could be formulated as follows:
select parent.*
from country_subdivisions parent
where parent.HasBoundaries = 1
and 0 < (select case
when count(*) = 0 then 1
else count(case when child.HasBoundaries = 0 then 1 end)
end
from country_subdivisions child
where child.Level.GetAncestor(1) = parent.Level
);

Hierarchic data with string paths - query for a node, get all parents and first level of their nodes

Say I got tree data:
- A A
- A0 A/A0
- A0.0 A/A0/A0.0
- A0.1 A/A0/A0.1
- A1 A/A1
- A1.0 A/A1/A1.0
- A1.1 A/A1/A1.1
- A2 A/A2
It is stored within a postgresql database "tree-data", with a column 'id' that is the path of the node like above and some helper columns like 'depth' (integer, representing the nodes depth in the tree), 'terminal' (boolean, is a leaf node and has no children).
What I'd like to achieve now is a query for 'A/A0/A0.0', that retrieves all parents and their first level of children.
Getting all parents is easy:
SELECT name, id, depth, terminal
FROM "tree-data"
WHERE 'A/A0/A0.0' LIKE id||'%'
ORDER BY id;
This will return the following nodes:
A
A/A0
A/A0/A0.0
But this is what I need:
A
A/A0
A/A0/A0.0
A/A0/A0.1
A/A1
A/A2
Can you think of an easy and efficient way of achieving this? Optimizing/modifying the schema is possible, though not preferred.
You can get the parent using regexp_replace() and then use the same logic you are using:
SELECT name, id, depth, terminal
FROM "tree-data"
WHERE 'A/A0/A0.0' LIKE regexp_replace(id, '/[^/]+$', '') || '%'
ORDER BY id;

Undirected graph in Oracle SQL

I'm trying to represent undirected graph in Oracle SQL, for example, I have stations graph:
CREATE TABLE station (
station_id INTEGER NOT NULL
);
CREATE TABLE station_link (
from_station INTEGER NOT NULL,
to_station INTEGER NOT NULL
);
This is obviously directed graph, but I have no idea, how to make it undirected.
Point: I need to get all vertices, which have path to current vertex and information about their level (how many vertices on this path).
For directed graph it is pretty easy:
SELECT sl.to_station, LEVEL
FROM station_link sl
START WITH sl.from_station = :curVertex
CONNECT BY NOCYCLE PRIOR sl.to_station = sl.from_station
But so we will get only one-way verticies.
Question: Do this problem have solution, except adding additional links (2 -> 1 for 1 -> 2)?
There is sql fiddle for tests: http://sqlfiddle.com/#!4/6c09e/24
For a "fast win" you can use your structure "as is", but for every edge you shold have two records in station_link table.
If you want "not_so_fast_but_without_doble_edge_records_please win", you can use this weirdo-trick:
SELECT
x.TO_STATION,
x.LVL
FROM (
SELECT sl.to_station, LEVEL as lvl
FROM station_link sl
START WITH sl.from_station = :curVertex
CONNECT BY NOCYCLE PRIOR sl.to_station = sl.from_station
UNION ALL
SELECT sl.from_station as to_station , LEVEL as lvl
FROM station_link sl
START WITH sl.to_station = :curVertex
CONNECT BY NOCYCLE PRIOR sl.from_station = sl.to_station
) x
It will do the work. Actually, it just combines two traversal directions.
But if I'll want to implement some serious algorithms on graphs in PLSQL, I would look to SDO_GEOMETRY data type and Oracle Spatial And Graphs Datasheets.

OrientDB select Vertex, Edge pairs from query

In an OrientDb graph database, I'm trying to get some information about Vertex, Edge pairs.
For example, consider the following case:
V1 ---E1---> V2
---E2---> V3 --E3--> V2
I would like to have as result the following 3 rows;
V1, E1
V1, E2
V3, E3
I've tried the following:
select label, flatten(out.label) from V
select label from (select flatten(out) from V)
select label, flatten(out) from V
select flatten(out) from V
select $current, label from (traverse out from V while $depth <= 1) where $depth = 1
But none of these solutions seem to return what I want. How can I return Vertex, Edge pairs?
What you are trying to do is actually extremely simple with OrientDB, it seems you are overthinking the issue.
Let's create your example:
V1 ---E1---> V2
---E2---> V3 --E3--> V2
In OrientDB, you would do this as follows:
/* Create nodes */
CREATE CLASS Node EXTENDS V
CREATE PROPERTY Node.name STRING (MANDATORY TRUE)
CREATE VERTEX Node SET name = 'V1'
CREATE VERTEX Node SET name = 'V2'
CREATE VERTEX Node SET name = 'V3'
/* Create edges */
CREATE CLASS Link EXTENDS E
CREATE PROPERTY Link.name STRING (MANDATORY TRUE)
CREATE EDGE Link
FROM (SELECT FROM Node WHERE name = 'V1')
TO (SELECT FROM Node WHERE name = 'V2')
SET name = 'E1'
CREATE EDGE Link
FROM (SELECT FROM Node WHERE name = 'V1')
TO (SELECT FROM Node WHERE name = 'V3')
SET name = 'E2'
CREATE EDGE Link
FROM (SELECT FROM Node WHERE name = 'V3')
TO (SELECT FROM Node WHERE name = 'V2')
SET name = 'E3'
This creates the following graph:
Now a little explanation of how to query in OrientDB. Let's say you load one vertex: SELECT * FROM Node WHERE name = 'V1'. Then, to load other information, you use:
To load all incoming vertices (skipping the edges): in()
To load all incoming vertices of class Link (skipping the edges): in('Link')
To load all incoming edges: inE()
To load all incoming edges of class Link: inE('Link')
To load all outgoing vertices (skipping the edges): out()
To load all outgoing vertices of class Link (skipping the edges): out('Link')
To load all outgoing edges: outE()
To load all outgoing edges of class Link: outE('Link')
So in your case, you want to load all the vertices and their outgoing edges, so we do:
SELECT name, outE('Link') FROM Node
Which loads the name of the vertices and a pointer to the outgoing edges:
If you would like to have a list of the names of the outgoing edges, we simply do:
SELECT name, outE('Link').name FROM Node
Which gives:
Which is exactly what you asked for in your question. As you can see, this is extremely simple to do in OrientDB, you just need to realize that OrientDB is smarter than you think :)
FLATTEN operator works alone, because get a field and let it to become the result. I don't understand what you want to do. Can you write the expected output please?
The CYPHER syntax, as used in Neo4j finally rescued me.
start n=node(*) MATCH (n)-[left]->(n2)<-[right]-(n3) WHERE n.type? ='myType' AND left.line > right.line - 1 AND left.line < right.line + 1 RETURN n, left, n2, right, n3
The node n is the pivoting element, on wich an filter can be provided, just as on each other step within the path. For me it was important to select a further step depending on an other part of the path.
With OrientDb I couldnt find a way to relate the properties to each other easily.

only select 5 newest posts

I have a database table containing the news on my site. It's divided into to group - team and board. I connect using LINQ.
The team news are being shown on all pages and the board news are being shown only on the front page.
I have tried this, because i want the 5 newest entires about team to be shown:
var query = from esh in gr.nyheders
where esh.typeBeskrivelse.Equals("team") && esh.id > ((from es in gr.nyheders where esh.typeBeskrivelse.Equals("team") select es.id).Max() - 5)
orderby esh.dato descending
select esh;
But it only shows two, since the 2 team news have ID <= 5.
how do I select the 5 newest team posts??
There is a Take method, that can be given a number of records to return. Take a look at http://msdn.microsoft.com/de-de/library/bb503062.aspx for more information