SQL 7
SQL 7
PRACTICAL NO: 07
Neo4j’s developer pages cover the basics of the language, which you can explore by
topic area below, starting with basic material, and building up towards more complex
material.
provides first class support for a number of data types. These fall into several
categories which will be described in detail in the following subsections:
Property types: Integer, Float, String, Boolean, Point, Date, Time, LocalTime,
DateTime, LocalDateTime, and Duration.
Structural types: Node, Relationship, and Path. Composite types: List and Map
In , comments are added by starting a line with // and writing text after the slashes.
Using two forward slashes designates the entire line as a comment, explaining syntax
or query functionality.
In , representing nodes involves enclosing them in parentheses, mirroring the visual
representation of circles used for nodes in the graph model. Nodes, which signify data
entities, are identified by finding nouns or objects in the data model. For instance, in
the example (Sally), (John), (Graphs), and (Neo4j) are nodes.
Logical Logs:
- Logical transaction logs are crucial for recovery after an unclean shutdown and
incremental backups.
- Log files are rotated after reaching a specified size (e.g., 25 MB).
- Configure log retention policy using the `dbms.tx_log.rotation.retention_policy`
parameter (recommended: 7 days).
Number of Open Files:
- The default open file limit of 1024 may be insufficient, especially with multiple
indexes or high connection volumes.
- Increase the limit to a practical value (e.g., 40000) based on usage patterns.
- Adjust system-wide open file limit following platform-specific instructions
(ulimit command for current session).
Real-world graph database scenarios
Example #1: Using Neo4j to determine customer preferences
Suppose we need to learn preferences of our customers to create a promotional
offer for a specific product category, such as notebooks. First, Neo4j allows us to
quickly obtain a list of notebooks that customers have viewed or added to their wish
lists. We can use this code to select all such notebooks:
MATCH (:Customer)- [:ADDED_TO_WISH_LIST|:VIEWED] - >
(notebook:Product) - [:IS_IN]->(:Category {title: 'Notebooks'})
RETURN notebook;
Now that we have a list of notebooks, we can easily include them in a
promotional offer. Let’s make a few modifications to the code above:
CREATE(offer:PromotionalOffer {type: 'discount_offer', content:
'Notebooks discount offer...'})
WITH offer
MATCH (:Customer)-[:ADDED_TO_WISH_LIST|:VIEWED]-
>(notebook:Product)- [:IS_IN]->(:Category {title: 'Notebooks'})
MERGE(offer)-[:USED_TO_PROMOTE]->(notebook);
We can track the changes in the graph with the following query:
MATCH (offer:PromotionalOffer)- [:USED_TO_PROMOTE]- (product:Product)
RETURN offer, product;
Linking a promotional offer with specific customers makes no sense, as the structure of graphs
allows you to access any node easily. We can collect emails for a newsletter by analyzing the
products in our promotional offer.
When creating a promotional offer, it’s important to know what products customers have viewed or
added to their wish lists. We can find out with this query:
MATCH (offer:PromotionalOffer {type: 'discount_offer'})-
[:USED_TO_PROMOTE]-
>(product:Product)<-[:ADDED_TO_WISH_LIST|:VIEWED]-
(customer:Customer)
RETURN offer, product, customer;
This example is simple, and we could have implemented the same functionality
in a relational database. But our goal is to show the intuitiveness of and to
demonstrate how simple it is to write queries in Neo4j.
Example #2: Using Neo4j to devise promotional offers
Now let’s imagine that we need to develop a more efficient promotional
campaign. To increase conversion rates, we should offer alternative products to our
customers. For example, if a customer shows interest in a certain product but doesn’t
buy it, we can create a promotional offer that contains alternative products.
To show how this works, let’s create a promotional offer for a specific
customer:
MATCH (alex:Customer {name: 'Alex McGyver'}) MATCH (free_product:Product)
WHERE NOT ((alex)-->(free_product)) MATCH (product:Product)
WHERE ((alex)-->(product))
MATCH (free_product)-[:IS_IN]->()<-[:IS_IN]-(product)
WHERE ((product.price - product.price * 0.20) >= free_product.price <=
(product.price + product.price * 0.20))
RETURN free_product;
This query searches for products that don’t have either ADDED_TO_WISH_LIST,
VIEWED, or BOUGHT relationships with a client named Alex McGyver. Next, we perform an
opposite query that finds all products that Alex McGyver has viewed, added to his wish list,
or bought. Also, it’s crucial to narrow down recommendations, so we should make sure that
these two queries select products in the same categories. Finally, we specify that only
products that cost 20 percent more or less than a specific item should be recommended to
the customer.
Now let’s check if this query works correctly.
The product variable is supposed to contain the following items:
Xiaomi Mi Mix 2 (price: $420.87). Price range for recommendations: from $336.70 to
$505.04. Sony Xperia XA1 Dual G3112 (price: $229.50). Price range for recommendations:
from
$183.60 to $275.40.
The free_product variable is expected to have these items:
Apple iPhone 8 Plus 64GB (price: $874.20) Huawei P8 Lite (price: $191.00)
Samsung Galaxy S8 (price: $784.00) Sony Xperia Z22 (price: $765.00)
Note that both product and free_product variables contain items that belong to the
same category, which means that the [:IS_IN]->()<-[:IS_IN] constraint has worked.
As you can see, none of the products except for the Huawei P8 Lite fits in the price
range for recommendations, so only the P8 Lite will be shown on the recommendations list
after the query is executed.
Now we can create our promotional offer. It’s going to be different from the previous
one (personal_replacement_offer instead of discount_offer), and this time we’re going to
store a customer’s email as a property of the USED_TO_PROMOTE relationship as the
products contained in the free_product variable aren’t connected to specific customers.
Here’s the full code for the promotional offer:
As you can see, Alex has two touch points with other customers: the Sony Xperia XA1
Dual G3112 (purchased by Allison York) and the Nikon D7500 Kit 18–105mm VR (viewed
by Joe Baxton). Therefore, in this particular case, our product recommendation system
should offer to Alex those products that Allison and Joe are interested in (but not the
products Alex is also interested in). We can implement this simple recommendation system
with the help of the following query:
MATCH (:Customer {name: 'Alex McGyver'})-->(product:Product)<--
(customer:Customer)
MATCH (customer)-->(customer_product:Product)
WHERE (customer_product <> product)
RETURN customer, customer_product;
We can further improve this recommendation system by adding new conditions, but the
takeaway is that Neo4j helps you build such systems quickly and easily.
(1) In , the WHERE clause is used to specify conditions for filtering query results. (True/False)
Ans:
(2) The CREATE clause in is used to find patterns in the graph. (True/False)
Ans:
(3) 's DELETE clause is used exclusively for removing nodes from the graph.
(True/False)
Ans:
This query creates a new node with the label Movie and sets its properties title to "Inception" and
releaseYear to 2010.
MATCH (a:Actor)-[:ACTED_IN]->(m:Movie)
WHERE m.releaseYear > 2000
RETURN a.name
This query matches relationships between Actor and Movie nodes where the releaseYear property
of the Movie node is greater than 2000. It then returns the name property of the Actor nodes.
This query matches the Movie node with the title "The Matrix" and updates its releaseYear property
to 1999.
MATCH (p:Person)-[r:RATED]->(m:Movie)
DELETE r
This query matches any relationship (r) with the type RATED between a Person and Movie node. It
then deletes the matched relationship.
MATCH (d:Director)-[:DIRECTED]->(m:Movie)
WHERE m.rating > 8
RETURN d.name
This query matches relationships between Director and Movie nodes where the rating property of
the Movie node is greater than 8. It then returns the name property of the Director nodes.
This query creates a new node with the label Actor and sets its name property to "Tom Hanks".
This query finds relationships between two Actor nodes connected through the same Movie node. It
excludes actors who acted in the same movie alone (a1.name <> a2.name) and returns their names.
MATCH (u:Person)-[:RATED]->(m:Movie)
WHERE m.rating > 4
RETURN u.name
This query matches relationships between Person and Movie nodes with the type RATED where the
rating property of the Movie node is greater than 4. It then returns the name property of the Person
nodes.
This query matches a Person node with the name "Alice" and a Movie node with the title "The
Shawshank Redemption". It then creates a new relationship of type RATED between them.
MATCH (m:Movie)
WHERE m.releaseYear >= 2010 AND m.releaseYear <= 2020
RETURN m.title
These queries should help you perform various operations and retrieve specific information from
your Neo4j graph database. Adjust them as needed based on your data model and requirements.
ASSESSMENT RUBRICS
Needs
Criteria Excellent (10) Good (7) Satisfactory (5) Marks
Improvement
(3)
Shows a high
Mastery of Demonstrates Demonstrates Struggles with
level of
Query exceptional basic proficiency queriesand
proficiency in
Language proficiency in in queries lacks
queries
queries proficiency
------------
Signature with date