Before we can start that exploration, we do need to put in place a few additional indexes that have not yet been created in the import process: on the english translations of the hadiths, and on the scholar names. That's simple operation:
CREATE TEXT INDEX hadith_text_en FOR (h:Hadith) ON (h.text_en);
CREATE TEXT INDEX scholar_name FOR (s:Scholar) ON (s.name);
Note that these indexes are not full text indexes - but they are more optimised for text fields.
The model now looks like this:
So now we can start some querying. This query gives us a flavour of what we could find:
MATCH (:Scholar)--(n:Hadith)--(:Source)
RETURN n LIMIT 25;
This is what that looks like:
Now let's look at some very specific network members. We'll start with a very well known scholar, Isma'il bin Ja'far.
Zooming into the Narration network for Isma'il bin Ja'far
Here's how we do that, at a very limited depth:
MATCH path = (s:Scholar)-[:NARRATED]->(h:Hadith)<-[:NARRATED]-(s2:Scholar)
WHERE s.name starts WITH "Isma'il bin Ja'far"
RETURN path;
We can of course also look at the Hadith chains that this particular scholar has been part of.
This is now also very simple:
MATCH (s:Scholar)-[hc1:HADITH_CHAIN]->(s2:Scholar)
WHERE s.name starts WITH "Isma'il bin Ja'far"
WITH s,hc1,s2,collect(hc1.hadith_id) as hadiths
MATCH path = (s2)-[hc2:HADITH_CHAIN*..15]->(:Scholar)
WHERE all(r in hc2 WHERE r.hadith_id in hadiths)
RETURN s,hc1, path
And similarly, we can also look at the aggregated hadith chains for this particular narrator:
MATCH path = (s:Scholar)-[ahc:AGGREGATED_HADITH_CHAIN*..5]->(s2:Scholar)
WHERE s.name starts WITH "Isma'il bin Ja'far"
and all(hc in ahc WHERE hc.nr_of_hadiths>10)
RETURN path;
In this Neo4j Browser visualisation that looks like this:
But if you apply a Neo4j Bloom perspective, have rule based styling on the relationhip (which will make the relationship thicker if the nr_of_hadiths
property is higher), and also apply a filter to weed out the relationships with a nr_of_hadiths
property lower than 10, then it looks like this:
As a final exploration step, I decided to take a look at some interesting topical Hadiths - by searching the (:Hadith)
nodes' text_en
property - containing the English translation of the Hadith's specific text in arabic. Since I don't speak a word of Arabic, search the English translation for keywords would be the only way to get a sense for the topical information... And of course, for me, that meant that I would want to take a look at the Hadith chains with regards to alcohol. Let's see what that would look like.
Here's a very nice and clean example:
MATCH path = (h:Hadith)--(s:Scholar)-[hc:HADITH_CHAIN*..10]-(:Scholar)
WHERE h.text_en contains "alcohol"
AND ALL(r IN hc WHERE r.hadith_id = h.hadith_id)
RETURN path
LIMIT 10;
And similar to the enhanced styling that we did above for the aggregated counts of hadiths on the relationship between Scholars, we can als make use of Bloom in a cool way by parametrising the topic upon which we search. All we need to do is define it in Bloom's search phrases, and introduce the $param
value where we would before define "alcohol"
.
MATCH path = (h:Hadith)--(s:Scholar)-[hc:HADITH_CHAIN*..10]-(:Scholar)
WHERE h.text_en contains $param
AND ALL(r IN hc WHERE r.hadith_id = h.hadith_id)
RETURN path
LIMIT 10;
So this is giving us a really nice view on these networks - tons of further investigation and exploration is of course possible. But I thought I would take it to another level, and do some playing around with the Neo4j Graph Data Science library.
Looking forward already!
Rik
PS: as always all the code/queries are available on github!
PPS: you can find all the parts in this blogpost on the following links
No comments:
Post a Comment