Write and execute a query to return the movie titles where they are ordered from the highest to the lowest imdbRating value. In your query, only return movies that have a value for the imdbRating property. How many Movie titles are returned?
이 문제의 핵심은 imdbRating value를 Descending order로 정렬하여 출력하라는 것이다.
MATCH (m:Movie)
WHERE m.imdbRating IS NOT NULL
RETURN m.title AS title, m.imdbRating AS rating
ORDER BY rating DESC
두가지 조건을 만족시키도록 쿼리를 수정하고, 가장 높은 점수를 받고, 가장 어린 배우를 찾으라는 문제이다. 즉, ORDER BY
쿼리에서 하나만이 아니라 다수의 feature를 사용하여 정렬 할 수 있음을 알려주는 문제라 할 수 있겠다.
MATCH (m:Movie)<-[:ACTED_IN]-(a:Actor)
WHERE m.imdbRating IS NOT NULL
RETURN m.title, a.name
ORDER BY m.imdbRating DESC, a.year DESC # Band of Brothers, Scott Grimes
A movie has a property, imdbRating. Not all movies have a value for this property. Write and execute a query to determine the lowest imdbRating that a movie has in our graph. What is the lowest imdbRating?
하나만 가져오려면 LIMIT
clause를 사용해 해 하결할 수 있다. LIMIT
는 pagination에서 자주 사용되는 것으로, 대규모 데이터에서 일부 데이터만 가져오려고 할때 빠른 시간내에 데이터를 가져올 수 있어 유용할 뿐만 아니라 SKIPS
clause 와 함께 사용하여 데이터를 스킵하고 중간부터 가져올 수 있다.
MATCH (m:Movie)
WHERE m.imdbRating IS NOT NULL
RETURN m.title, m.imdbRating
ORDER BY m.imdbRating ASC
LIMIT 1
유일한 데이터만 가져오고 싶을 때는 DISTINCT
clause를 붙여 가져오면 된다. 단, 전체 피처에 하나만 DISTINCT
를 넣을 수 있다. 예를 들어 (a, b), (a, c) 의 2 feature를 가지는 결과를 가져올 때, a가 중복되더라도 b, c가 다름으로 다른 값으로 반환한다.
문제에서는 영화 Toy Story를 감독하거나 연기했던 모든 사람중에 같은 영화에서 연기했던 사람들을 찾아내라는 것이다. 단, 중복은 허용하지 않는다고 한다.
MATCH (p:Person)-[:ACTED_IN| DIRECTED]->(m)
WHERE m.title = 'Toy Story'
MATCH (p)-[:ACTED_IN]->()<-[:ACTED_IN]-(p2:Person)
RETURN DISTINCT p.name, p2.name
그냥 RETURN
앞에 DISTINCT
붙여주면 된다.
neo4j는 특정 properties 만 json 형태로 가져올 수 있다.
예를 들어
MATCH (m:Movie)<-[:DIRECTED]-(d:Director)
WHERE d.name = 'Woody Allen'
RETURN m {.title, .released} AS movie ORDER BY m.released
위의 query는 movie 에서 title과 released property만 가져오겠다는 것이다. 모든 properties를 가져오는 것은 { .* }
를 사용하면 된다. 그냥 m 써 주는 것과 동일하다.
조건부로 데이터를 변경하여 결과를 출력하는 방법이 있는데, CASE
clause를 이용하면 된다.
MATCH (m:Movie)<-[:ACTED_IN]-(p:Person)
WHERE p.name = 'Henry Fonda'
RETURN m.title AS movie,
CASE
WHEN m.year < 1940 THEN 'oldies'
WHEN 1940 <= m.year < 1950 THEN 'forties'
WHEN 1950 <= m.year < 1960 THEN 'fifties'
WHEN 1960 <= m.year < 1970 THEN 'sixties'
WHEN 1970 <= m.year < 1980 THEN 'seventies'
WHEN 1980 <= m.year < 1990 THEN 'eighties'
WHEN 1990 <= m.year < 2000 THEN 'nineties'
ELSE 'two-thousands'
END
AS timeFrame
문법은 CASE WHEN ... ELSE ... END
이다.
MATCH (m:Movie)<-[:ACTED_IN]-(p:Person)
WHERE p.name = 'Charlie Chaplin'
RETURN m.title AS movie,
// Add CASE clause code here
m.runtime AS runTime
만일 movie의 runTime이 120분 미만이면 'Short'를, 그 이상이면 'Long'을 출력하는 CASE
구문을 사용한 조건부 쿼리를 짜라는 문제이다. 문제 자체는 short인 결과의 개수를 세라는 것임으로 WITH 구문을 이용하여 살짝 바꾸면 아래와 같다.
MATCH (m:Movie)<-[:ACTED_IN]-(p:Person)
WHERE p.name = 'Charlie Chaplin'
WITH
CASE
WHEN m.runtime < 120 THEN 'Short'
ELSE 'Long'
END AS movieRuntimeType
WHERE movieRuntimeType = 'Short'
RETURN count(movieRuntimeType) # 6