Queries to be tested in Neo4j - graph

Why I can't get any results with this queries? What I'm doing wrong here?
QUERY 1
MATCH (person:Person)-[:PRS_knows_PRS*1..2]-(friend:Person),
(friend)<-[:CMT_hasCreator_PRS]-(friendPost:Post)-[:PST_hasTag_TAG]->(knownTag:Tag {nameTag:2})
WHERE not(person=friend)
MATCH (friendPost)-[:PST_hasTag_TAG]->(commonTag:Tag)
WHERE not(commonTag=knownTag)
WITH DISTINCT commonTag, knownTag, friend
MATCH (commonTag)<-[:PST_hasTag_TAG]-(commonPost:Post)-[:PST_hasTag_TAG]->(knownTag)
WHERE (commonPost)-[:CMT_hasCreator_PRS]->(friend)
RETURN
commonTag.nameTag AS tagName,
count(commonPost) AS postCount
ORDER BY postCount DESC, tagName ASC
LIMIT 3
QUERY 2
MATCH (person:Person)-[:PRS_knows_PRS*1..2]-(friend:Person)
WHERE not(person=friend)
WITH DISTINCT friend
MATCH (friend)-[worksAt:PRS_worksAt_ORG]->(company:Organisation)-[:ORG_isLocatedIn_PLC]->(:Country {name:{3}})
WHERE worksAt.workFromPWAO < {2}
RETURN
friend.idPerson AS friendId,
friend.firstNamePerson AS friendFirstName,
friend.lastNamePerson AS friendLastName,
worksAt.workFromPWAO AS workFromYear,
company.nameOrganisation AS companyName
ORDER BY workFromYear ASC, friendId ASC, companyName DESC
LIMIT 4
I have this nodes, property Keys and relatioship types:
Could you please help me with this problem?

On your query you use this relationship name:
worksAt:PRS_worksAt_ORG
but on your screen shot of the properties the relationship is called 'PRS_workAt_ORG' without the 's' on workAt.
Maybe that's what's missing on the second query?

Usually it helps to build up the queries step by step.
Then you see where they stop returning data.
A PROFILE (prefix) of your queries should also help to see where it starts to return ZERO rows.
Could also be a case-typo in one of the labels and rel-types.

Related

Symfony order by the content of a specific field

I want to sort data in repository based on the content of a specific field
For example i have an entity person with the fields role,fistName and lastName.
I would like to sort using ->orderBy('p.role', ???) and get a list ordered based on this order : professors then directors then teachers and at last students .
Example of my database:
Wanted result:
Ps: i can not use ASC or DESC since my sorting order is neither ASC nor DESC;
it is a custom order
Very strage scenario, you could use a CASE statement in order to assing a custom value for each fields then sort on him.
You could use the HIDDEN keyword.
As example take a look at this DQL:
SELECT p, CASE
WHEN p.role = "professor" THEN 1
WHEN p.role = "director" THEN 2
WHEN p.role = "teacher" THEN 3
WHEN p.role = "student" THEN 4
ELSE 99 END
AS HIDDEN mySortRule
FROM Bundle\Entity\Person p
ORDER BY mySortRule ASC
Hope this help

What's the equivalent DynamoDB solution for this MySQL Query?

I'm familiar with MySQL and am starting to use Amazon DynamoDB for a new project.
Assume I have a MySQL table like this:
CREATE TABLE foo (
id CHAR(64) NOT NULL,
scheduledDelivery DATETIME NOT NULL,
-- ...other columns...
PRIMARY KEY(id),
INDEX schedIndex (scheduledDelivery)
);
Note the secondary Index schedIndex which is supposed to speed-up the following query (which is executed periodically):
SELECT *
FROM foo
WHERE scheduledDelivery <= NOW()
ORDER BY scheduledDelivery ASC
LIMIT 100;
That is: Take the 100 oldest items that are due to be delivered.
With DynamoDB I can use the id column as primary partition key.
However, I don't understand how I can avoid full-table scans in DynamoDB. When adding a secondary index I must always specify a "partition key". However, (in MySQL words) I see these problems:
the scheduledDelivery column is not unique, so it can't be used as a partition key itself AFAIK
adding id as unique partition key and using scheduledDelivery as "sort key" sounds like a (id, scheduledDelivery) secondary index to me, which makes that index pratically useless
I understand that MySQL and DynamoDB require different approaches, so what would be a appropriate solution in this case?
It's not possible to avoid a full table scan with this kind of query.
However, you may be able to disguise it as a Query operation, which would allow you to sort the results (not possible with a Scan).
You must first create a GSI. Let's name it scheduled_delivery-index.
We will specify our index's partition key to be an attribute named fixed_val, and our sort key to be scheduled_delivery.
fixed_val will contain any value you want, but it must always be that value, and you must know it from the client side. For the sake of this example, let's say that fixed_val will always be 1.
GSI keys do not have to be unique, so don't worry if there are two duplicated scheduled_delivery values.
You would query the table like this:
var now = Date.now();
//...
{
TableName: "foo",
IndexName: "scheduled_delivery-index",
ExpressionAttributeNames: {
"#f": "fixed_value",
"#d": "scheduled_delivery"
},
ExpressionAttributeValues: {
":f": 1,
":d": now
},
KeyConditionExpression: "#f = :f and #d <= :d",
ScanIndexForward: true
}

Query to find 'most watched' [COUNT()] from one table while returning the results from another

The question probably is quite confusing.
In affect i have the following:
WatchList table
UserId | FilmId
| 3 77
| etc etc
|
|
|
these are foreign keys for the following tables
FilmDB - Film_title, Film_plot, Film_Id etc.
and
aspnet_memberships - UserId, Username etc..
Now, i presume i will need to use a join but i am struggling with the syntax.
I would like to use 'Count' on the 'WatchList' and return the most frequent filmId's and their counterpart information, but i'd then like to return the REST of the FilmDB results, essentially giving me a list of ALL films, but with those found in the WatchedList my frequently sorted to the top.
Does that make sense? Thanks.
SELECT *
FROM filmdb
LEFT JOIN (
SELECT filmid, count(*) AS cnt
FROM watch_list
GROUP BY filmid) AS a
ON filmdb.film_id = a.filmid
ORDER BY isnull(cnt, 0) DESC;
http://sqlfiddle.com/#!3/46b16/10
You did not specify if the query should be grouped by film_id or user_id. The example I have provided is grouped by user if you change that to film_id then you will get the watch count for all users per film.
You need to use a subquery to get the count and then order the results by the count descending to get an ordered list.
SELECT
*
FROM
(
SELECT
WatchList.Film_Id,
WatchCount=COUNT(*)
FilmDB.Film_Title
FROM
WatchList
INNER JOIN FilmDB ON FilmDB.Film_Id=WatchList.Film_Id
GROUP BY
WatchList.UserID,
WatchList.Film_Id,
FilmDB.Film_Title
)AS X
ORDER BY
WatchCount DESC

sqlite passing result from a subquery as LIKE argument

I have a query where I want to delete all the entries which belongs to a date. I am missing how to pass a LIKE argument from the sub-query. The idea is to match a date from the last entry and delete all the matched entries.
DELETE FROM logentries WHERE datetime(timestamp) LIKE----(SELECT date(timestamp) FROM logentries ORDER BY datetime(timestamp) ASC LIMIT 1);
How to have the above 2 queries in a single query?
Don't use LIKE (there's no pattern matching here), use =:
DELETE FROM logentries WHERE DATE(timestamp) = (SELECT DATE(timestamp) FROM logentries ORDER BY timestamp DESC LIMIT 1);
You must convert your dates to string and it will do the trick.

Complex sqlite query, what's the correct syntax?

The query is this one:
SELECT FriendID FROM Relationships WHERE UserID = 1
INTERSECT
(SELECT FriendID FROM Relationships WHERE UserID = 2
UNION SELECT UserID FROM Relationships WHERE FriendID = 2)
(for the curious readers, please note that the friend relationship is not necessarily symmetrical in this scenario)
I've tried all the possible combination of parentheses with no luck.
If I omit the parentheses, there's no operator precedence in the sense that it reads it like 5+6*3 = 33, so if I put the union before the intersection, the query works fine. But what will I do when I will have to intersect two unions?
You can use temporary tables in such case.
Thanks to Larry Lustig (which pointed me this), I rewrote my query as follows
SELECT FriendID FROM Relationships WHERE UserID = 1
INTERSECT SELECT ID FROM
(SELECT FriendID AS ID FROM Relationships WHERE UserID = 2
UNION SELECT UserID AS ID FROM Relationships WHERE FriendID = 2)
And it works.

Resources