Why Semantic Databases are so Important – Discovering Shared Meaning

An excerpt from my upcoming article that I wanted to share separately from the full article, as it is an excellent example of one reason semantic databases are so important — the ability to discover shared meaning.

Being able to discover implicit associations is one of the unique features of a semantic database.  Given three semantic types:

  1. Person
  2. Date
  3. MonthLookup

implemented with the following semantic schema:

threefoldSchema.png
Our “discovery” method determines the following associations (left-to-right is bottom-most to top-most):

month <- monthLookup
month <- date
  
name <- monthName <- monthLookup
name <- firstName <- personName <- person
  
name <- monthName <- monthLookup
name <- lastName <- personName <- person
  
name <- monthAbbr <- monthLookup
name <- firstName <- personName <- person
  
name <- monthAbbr <- monthLookup
name <- lastName <- personName <- person

From this, we could construct a query where we can say “give me all the dates whose month’s name is also the person’s first name”.  This would follow the association chain like this:

associations1

 

 

 

If we populate the month lookup semantic records with the obvious 12 months of the year, and the person an date semantic records with (flattened view here):

{month: 8, day: 19, year: 1962}
{month: 4, day: 1, year: 2016}

and (again, flattened view here):

{firstName: 'Marc', lastName: 'Clifton'}
{firstName: 'April', lastName: 'Jones'}

We can then write a MongoDB query, based on the discovered shared meaning:

db.firstName.aggregate(
// firstName -> name
{ $lookup: {from: ‘name’, localField: ‘nameId’, foreignField: ‘_id’, as: ‘fname’} },
{ $unwind: ‘$fname’ },
// name -> monthName -> monthLookup
{ $lookup: {from: ‘monthName’, localField: ‘fname._id’, foreignField: ‘nameId’, as: ‘monthName’} },
{ $unwind: ‘$monthName’ },
{ $lookup: {from: ‘monthLookup’, localField: ‘monthName._id’, foreignField: ‘monthNameId’, as: ‘monthLookup’} },
{ $unwind: ‘$monthLookup’},
// monthLookup -> month
{ $lookup: {from: ‘month’, localField: ‘monthLookup.monthId’, foreignField: ‘_id’, as: ‘month’} },
{ $unwind: ‘$month’},
// month -> date
{ $lookup: {from: ‘date’, localField: ‘month._id’, foreignField: ‘monthId’, as: ‘date’} },
{ $unwind: ‘$date’},
// date.day -> day.value
{ $lookup: {from: ‘day’, localField: ‘date.dayId’, foreignField: ‘_id’, as: ‘day’} },
{ $unwind: ‘$day’},
// date.year -> year.value
{ $lookup: {from: ‘year’, localField: ‘date.yearId’, foreignField: ‘_id’, as: ‘year’} },
{ $unwind: ‘$year’},
{ $project: {‘monthName’: ‘$fname.name’, ‘month’: ‘$month.value’, ‘day’: ‘$day.value’, ‘year’: ‘$year.value’, ‘_id’:0} } )

Giving us the one matching record.

fnamemonthdate

 

 

 

 

What we’ve achieved here is quite interesting!  Because our database is semantic, the system knows that things like “month” and “name” have a shared meaning, so we can ask the schema “what entities have shared meaning” and we can weave through the hierarchies of the semantic types to combine types into new and interesting queries.  This kind of query could of course be expressed in SQL (and perhaps more simply), but we would be comparing non-semantic field values that the programmer decided had shared meaning, rather than the system discovering the shared meaning.  By letting the system discover the shared meaning, the user, not the programmer, can make new and interesting associations.

Leave a comment