// M ovi e S ch e ma
var c ri ti ci s ms Sc he m a = {
co l or : {t y pe : S tri ng ,
enu m : [ ’g r een ’ , ’ yellow ’, ’ red ’ ],
re qui red : tr u e},
jo ur n al ist :{typ e : S t ri n g , u n iq u e : tru e ,
re qui red : tr u e},
me d ia :{t y pe : S tri ng , r eq u ir ed : t rue},
url : S tr i ng
}
var p ri zes Sc he m a = {
ev e nt :{t y pe : S tri ng , r eq u ir ed : t rue},
na m es :{t y pe : [ St r in g ] , r eq u ir ed : t rue},
yea r : {ty pe : N u mb e r , r equ ire d : tr ue}
}
var m ov i eS ch e ma = n e w m on goo se . S c hem a ({
ti t le :{t y pe : St rin g , m ax l en gth : 40 ,
un i qu e : t rue , r eq uir ed : tr u e},
_id : {type : S tri ng , i ndex : t rue ,
re qui red : t rue},
yea r : {ty pe : Nu m ber , in dex : tr ue ,
re qui red : t rue},
typ e : {ty pe : St r ing , r e qu ire d : true},
di re c to r_ i d : {t y pe : S tri ng , r eq u ir e d : t r ue ,
ref : ’ D ire c tor ’},
ge n re : {t y pe : St rin g ,
enu m : [ ’d r ama ’ , ’ come d y ’ , ’ chi ldre n ’ ] ,
re qui red : t rue},
cr it i ci sms : {ty p e : cr it ic i sm sS ch e ma },
pr i ze s : {ty pe : pr iz e sS ch e ma }
},{co lle ct i on : ’ Movie ’}) ;
// a dd re qui red f or Mo v ie 1 en ti t y ve rsi on
mo vi e Sc he m a . pat h (’ cr iti c ism s ’) . r equ ire d () ;
mo vi e Sc he m a . pat h (’ pri z es ’) . r e qu ire d () ;
var M ovi e = mo ngo os e . m ode l (’ Movie ’ , m ovi eS che ma ) ;
// a dd Di rec to r 1 s c hem a re fe r en ce d b y M ov i e1
var d ir ec to r Sc he ma = new m ong oo s e . Sc h em a ({
_id : {typ e : S tri ng , i nde x : t rue ,
re qui red : t rue},
nam e : {typ e : S tri ng , u ni q ue : t rue ,
re qui red : t rue},
typ e : {typ e : S tri ng , r eq uir ed : tr u e},
ac to r _m ov i es : {typ e : S tri ng ,
ref : ’ M o vie ’},
di re ct e d_ mo vi e s : {t ype : St rin g ,
re qui red : t rue ,
ref : ’ M o vie ’}
},{co lle ct i on : ’ Dir ecto r ’});
// a dd f o r D ir ect or 1 e n ti t y Ve rsi on
di re cto rS ch e ma . p ath ( ’ act or_ m ov i es ’) . re q ui red () ;
var D ir e ct or = m ong oos e . mod el (’ D irec t or ’ ,
di re cto rS ch e ma ) ;
Figure 7: Generated Mongoose Schema.
erate Mongoose code involved in all these mecha-
nisms, we have created a domain-specific language
(DSL) aimed to specify the information needed for
such generation. This DSL is named ODM Parameter
Language and it is independent of a concrete mapper
technology. Figure 8 shows an example of specifi-
cation for the entities of our database example. This
DSL has been created with the Xtext (Xtext, 2016),
and models are obtained by means of the parser gen-
erated by this tool. These DSL models are input to
the m2t transformation that generates Mongoose arte-
facts from EntityDifferentiation models, as shown in
Figure 2.
In Mongoose, the validation is defined at the
schema level. Some frequently used validators are
already built-in. The require and unique validators
can be applied to any property. As explained in pre-
vious Section, we have used require to specify what
properties are common to all the versions. The unique
validator is used to express that all the documents of
a collection must have a different value for a field
of primitive type. Other examples of validators are
min and max for Number fields, and enum, minlength
and maxlength for String fields. Indexes are also de-
fined at schema level, for instance an index can be
specified with the index option or the unique validator
(which also implies the creation of an index). Ex-
amples of use of these validators are shown in the
schema in Figure 7. For instance an enumeration is
defined for the color field of Criticism and the title
field of Movie is unique. These validators have been
generated from the information provided by the DSL
specification shown in Figure 8.
Our schema inference mechanism cannot discover
the decisions behind a version entity. As indicated
above, version variation can be caused by different
reasons, such as requirement changes, non-uniform
data, or custom fields in entities. We have used the
required validator to specify which fields are part of
a particular entity version. However, Mongoose pro-
vides the discriminator mechanism to have collections
of non-uniform data types. This mechanism would
be more appropriate than the require option for non-
uniform data. For instance, a MovieTheaters could
register two kinds of movie theaters in our Movie
database: single screen or multiplexed theaters. The
name, city, country fields would be common, but the
roomNumber field would be only part of multiplexed
theaters. Figure 8 shows how to declare a discrimina-
tor for an entity, MovieTheater in the example. The
generated code is shown in Figure 9.
Mongoose provides update() helper methods, but
they do not apply validators, so the code to perform
updating must be written following three steps (find-
update-save). We also automate the generation of this
code. For instance, in Figure 10 we show the code
generated for updating the genre field of the Movie
schema.
MODELSWARD 2017 - 5th International Conference on Model-Driven Engineering and Software Development
226