Soit les données suivantes représentant des films de cinéma.
db.Cinema.drop()
db.Cinema.insert(
{
nom:"Goodfellas",
annee:1990,
realisateur:{nom:"Scorsese", prenom:"Martin"},
acteurs:
[
{nom:"De Niro", prenom:"Robert"},
{nom:"Liotta", prenom:"Ray"},
{nom:"Pesci", prenom:"Joe"}
]
})
db.Cinema.insert(
{
nom:"The Godfather",
annee:1972,
realisateur:{nom:"Coppola", prenom:"Francis Ford"},
acteurs:
[
{nom:"Pacino", prenom:"Al"},
{nom:"Brando", prenom:"Marlon"},
{nom:"Duvall", prenom:"Robert"}
]
})
db.Cinema.insert(
{
nom:"Million Dollar Baby",
realisateur:{nom:"Eastwood", prenom:"Clint"},
acteurs:
[
{nom:"Swank", prenom:"Hilary"},
{nom:"Eastwood", prenom:"Clint"}
]
})
db.Cinema.insert(
{
nom:"Gran Torino",
annee:2008,
realisateur:{nom:"Eastwood", prenom:"Clint"},
acteurs:
[
{nom:"Vang", prenom:"Bee"},
{nom:"Eastwood", prenom:"Clint"}
]
})
db.Cinema.insert(
{
nom:"Unforgiven",
realisateur:{nom:"Eastwood", prenom:"Clint"},
acteurs:
[
{nom:"Hackman", prenom:"Gene"},
{nom:"Eastwood", prenom:"Clint"}
]
})
db.Cinema.insert(
{
nom:"Mystic River",
realisateur:{nom:"Eastwood", prenom:"Clint"},
acteurs:
[
{nom:"Penn", prenom:"Sean"},
{nom:"Bacon", prenom:"Kevin"}
]
})
db.Cinema.insert(
{
nom:"Honkytonk Man",
realisateur:{nom:"Eastwood", prenom:"Clint"},
annee:1982,
acteurs:
[
{nom:"Eastwood", prenom:"Kyle"},
{nom:"Bloom", prenom:"Verna"}
]
})
db.Cinema.find()
L'objectif est d'initialiser une base MongoDB avec ce script, puis d'écrire les requêtes MongoDB permettant de répondre aux questions suivantes.
Créer une nouvelle base MongoDB et exécuter le script. Nommez votre base par votre nom de famille ou votre login sur la machine par exemple.
Pour créer une base de données, utiliser l'instruction use myNewDatabase
, puis exécuter au moins une instruction d'insertion.
Quels sont les films sortis en 1990 ?
db.Cinema.find(document JSON)
db.col.find({"attribute":"value"})
db.Cinema.find({"annee":1990})
Quels sont les films sortis avant 2000 ?
On utilisera l'objet {$lt:value}
à la place de la valeur de l'attribut à tester ($lt pour lesser than).
db.Cinema.find({"annee":{$lt:2000}})
Quels sont les films réalisés par Clint Eastwood ?
On utilisera un objet comme valeur.
db.Cinema.find({"realisateur":{"nom":"Eastwood", "prenom":"Clint"}})
Quels sont les films réalisés par quelqu'un prénommé Clint ?
Utiliser le navigateur de propriété des objets point : object.attribute.
db.Cinema.find({"realisateur.prenom":"Clint"})
Quels sont les films réalisés par quelqu'un prénommé Clint avant 2000 ?
Utiliser une liste de conditions attribut:valeur pour spécifier un AND (et logique) :
db.col.find({"attribute1":"value1", "attribute2":"value2"})
db.Cinema.find({"realisateur.prenom":"Clint", "annee":{$lt:2000}})
Quels sont les films dans lesquels joue Clint Eastwood ?
db.Cinema.find({"acteurs":{nom:"Eastwood", prenom:"Clint"}})
Quels sont les films dans lesquels joue un Eastwood ?
Utiliser le parser de tableau $elemMatch:{"key":"value"}
à la place de la valeur.
db.Cinema.find({"acteurs":{$elemMatch:{"nom":"Eastwood"}}})
Quels sont les noms des films dans lesquels joue un Eastwood ?
Pour gérer la projection, utiliser un second argument de la clause find() :
db.Cinema.find({document JSON de sélection }, {document JSON de projection})
avec document JSON de projection de la forme : {"attribut1":1, "attribut2":1...}
Les identifiants sont toujours affichés par défaut, si on veut les supprimer, on peut ajouter la clause _id:0
dans le document de projection.
db.Cinema.find({"acteurs":{$elemMatch:{"nom":"Eastwood"}}},{"nom":1,"_id":0})
Compléter le programme JavaScript suivant afin d'afficher les titre selon le format suivant :
- Million Dollar Baby
- Gran Torino
- Unforgiven
- Honkytonk Man
conn = new Mongo();
db = conn.getDB("...");
recordset = ...
while ( recordset.hasNext() ) {
film = recordset.next() ;
print("- ", ...);
}
conn = new Mongo();
db = conn.getDB("db1");
recordset = db.Cinema.find({"acteurs":{$elemMatch:{"nom":"Eastwood"}}},{"nom":1,"_id":0})
while ( recordset.hasNext() ) {
film = recordset.next() ;
print("- ", film.nom);
}
On veut à présent ajouter une nouvelle collection permettant de gérer des utilisateurs et leurs préférences. Pour chaque utilisateur on gérera un pseudonyme, et une liste de films préférés avec une note allant de une à trois étoiles.
Ajouter trois utilisateurs préférant chacun un ou deux films.
On utilisera les identifiants des films pour les référencer.
db.User.insert(
{
"pseudo":"Stph",
"liked" :
[
{"film":"590c366d70f50381c920ca71","star":3},
{"film":"590c366d70f50381c920ca72","star":1}
]
}
)
db.User.insert(
{
"pseudo":"Luke",
"liked" :
[
{"film":"590c366d70f50381c920ca71","star":2}
]
}
)
db.User.insert(
{
"pseudo":"Tuco",
"liked" :
[
{"film":"590c366d70f50381c920ca74","star":3}
]
}
)
Critiquer cette insertion mobilisant les identifiants des films ? Pourquoi n'est ce pas reproductible ?
Les identifiants sont contrôlés par le système, ils sont fixés lors de l'insertion, mais si l'on change de base de données, les identifiants seront différents.
Quels sont les utilisateurs qui aiment au moins un film avec 3 étoiles ?
db.User.find({"liked":{$elemMatch:{"star":3}}})
Quels sont les identifiants des films qui sont aimés au moins une fois avec 3 étoiles ?
db.User.find({"liked":{$elemMatch:{"star":3}}}, {"_id":0, "liked.film":1})
Pourquoi trouver les titres de ces films n'est pas simple avec Mongo ?
Comme Mongo ne gère pas de jointure, on va devoir la réaliser au niveau de la couche cliente applicative.
Interroger MongoDb avec la requête précédente
Récupérer et dédoublonner la liste des identifiants de films
Boucler sur ces identifiants, créer une requête pour chaque identifiant et interroger MongoDB
Par exemple : db.Cinema.find({"_id":ObjectId("574ddaa372ace929efdaa46f")})
Pour récupérer une liste de valeurs distinctes, on pourra cette requête :
db.User.distinct("liked.film", {"liked":{$elemMatch:{"star":3}}})
Cette requête renvoie directement un tableau et non un pointeur sur une liste d'enregistrements.
Pour récupérer une entrée par son identifiant on préférera cette requête :
db.Cinema.findOne(ObjectId('574ddaa372ace929efdaa46f'))
Écrire le programme JavaScript permettant de récupérer la liste dédoublonnée des identifiants de films qui sont aimés au moins une fois avec 3 étoiles, puis d'afficher les titres des films correspondants.
conn = new Mongo();
db = conn.getDB("...");
films = ...
for (var i=0; i<films.length; i++) {
var id = films[i];
if (film = ...)
print(...);
}
conn = new Mongo();
db = conn.getDB("db1");
films = db.User.distinct("liked.film", {"liked":{$elemMatch:{"star":3}}});
for (var i=0; i<films.length; i++) {
var id = films[i];
if (film = db.Cinema.findOne(ObjectId(id)))
print(film.nom);
}