Recherche…
Remarques
Une manière utile de penser aux collections Mongo est en termes de qui, quoi, quand, où, pourquoi et comment. Mongo dispose des optimisations suivantes pour différents types de données:
Où - GeoJSON
When - Horodatage ObjectID
Who - Les chaînes de compte Meteor
How - JSON pour les arbres de décision
Ce qui laisse le document par défaut dans Mongo représentant grosso modo un «quoi».
Création d'enregistrements dans une base de données existante
Vous pouvez utiliser le format Mongo normal par défaut en définissant vos collections avec le champ idGeneration.
MyCollection = new Meteor.Collection('mycollection', {idGeneration : 'MONGO'});
Insérer des données dans un document
De nombreux débutants à Mongo ont des difficultés avec les bases, telles que l'insertion d'un tableau, d'une date, d'une valeur booléenne, d'une variable de session, etc. dans un enregistrement de document. Cet exemple fournit des indications sur les entrées de données de base.
Todos.insert({
text: "foo", // String
listId: Session.get('list_id'), // String
value: parseInt(2), // Number
done: false, // Boolean
createdAt: new Date(), // Dimestamp
timestamp: (new Date()).getTime(), // Time
tags: [] // Array
});
Obtenir le _id du document le plus récemment créé
Vous pouvez l'obtenir soit de manière synchrone:
var docId = Todos.insert({text: 'foo'});
console.log(docId);
Ou de manière asynchrone:
Todos.insert({text: 'foo'}, function(error, docId){
console.log(docId);
});
Données de séries chronologiques
Utiliser MongoDB pour les séries chronologiques est un document très utile et un cas d'utilisation établi, avec des livres blancs et des présentations officiels. Lisez et regardez la documentation officielle de MongoDB avant d'essayer d'inventer vos propres schémas pour les données de séries chronologiques.
MongoDB pour les données de séries chronologiques
En général, vous voudrez créer des "buckets" pour les données de vos séries de temps:
DailyStats.insert({
"date" : moment().format("MM-DD-YYYY"),
"dateIncrement" : moment().format("YYYYMMDD"),
"dailyTotal" : 0,
'bucketA': 0,
'bucketB': 0,
'bucketC': 0
});
Et ensuite, incrémentez ces compartiments au fur et à mesure que les données alimentent votre application. Cet incrément peut être placé dans une méthode Meteor, un observateur de collection, un point de terminaison API REST et divers autres endroits.
DailyStats.update({_id: doc._id}, {$inc: {bucketA: 1} });
Pour un exemple plus complet de Meteor, consultez les exemples de la piste Clinical Meteor:
Pipeline d'analyse en temps réel
Clinical Meteor - Graphes - Dailystats
Filtrage avec des expressions régulières
Modèle simple pour filtrer les abonnements sur le serveur, en utilisant des expressions rationnelles, des variables de session réactives et des autoruns de deps.
// create our collection
WordList = new Meteor.Collection("wordlist");
// and a default session variable to hold the value we're searching for
Session.setDefault('dictionary_search', '');
Meteor.isClient(function(){
// we create a reactive context that will rerun items when a Session variable gets updated
Deps.autorun(function(){
// and create a subscription that will get re-subscribe to when Session variable gets updated
Meteor.subscribe('wordlist', Session.get('dictionary_search'));
});
Template.dictionaryIndexTemplate.events({
'keyup #dictionarySearchInput': function(evt,tmpl){
// we set the Session variable with the value of our input when it changes
Session.set('dictionary_search', $('#dictionarySearchInput').val());
},
'click #dictionarySearchInput':function(){
// and clear the session variable when we enter the input
Session.set('dictionary_search', '');
},
});
});
Meteor.isServer(function(){
Meteor.publish('wordlist', function (word_search) {
// this query gets rerun whenever the client subscribes to this publication
return WordList.find({
// and here we do our regex search
Word: { $regex: word_search, $options: 'i' }
},{limit: 100});
});
});
Et le HTML qui est utilisé sur le client:
<input id="dictionarySearchInput" type="text" placeholder="Filter..." value="hello"></input>
Ce modèle lui-même est assez simple, mais les expressions rationnelles peuvent ne pas l'être. Si vous n'êtes pas familier avec les regex, voici quelques tutoriels et liens utiles:
Tutoriel d'expression régulière
Feuille de triche d'expression régulière
Expressions régulières en Javascript
Collections géospatiales - Apprendre plus
Les collections géospatiales impliquent généralement de stocker GeoJSON dans la base de données Mongo, de transmettre ces données au client, d'accéder à window.navigator.geolocation
du navigateur, de charger une API Map, de convertir GeoJSON en LatLngs et de tracer sur la carte. De préférence tous en temps réel. Voici une liste de ressources pour vous aider à démarrer:
- mongodb stocke de manière optimale ses données dans geoJSON
- geojson.org
- window.navigator.geolocation
- Géolocalisation HTML
- Sélecteur d'API Maps
- google.maps.LatLng
- Google map.data.loadGeoJson
- fond météore-cordoue-géolocalisation
- phonegap-googlemaps-plugin
- LatLng
- maps.documentation
- google.maps.LatLng
- Index 2dsphere
- créer un index 2dsphere
- interroger un index 2dsphere
- index géospatiaux et requêtes
Auditer les requêtes de collection
L'exemple suivant enregistre toutes vos requêtes de collecte sur la console du serveur en temps réel.
Meteor.startup(
function () {
var wrappedFind = Meteor.Collection.prototype.find;
// console.log('[startup] wrapping Collection.find')
Meteor.Collection.prototype.find = function () {
// console.log(this._name + '.find', JSON.stringify(arguments))
return wrappedFind.apply(this, arguments);
}
},
function () {
var wrappedUpdate = Meteor.Collection.prototype.update;
// console.log('[startup] wrapping Collection.find')
Meteor.Collection.prototype.update = function () {
console.log(this._name + '.update', JSON.stringify(arguments))
return wrappedUpdate.apply(this, arguments);
}
}
);
Fonctions des observateurs et des travailleurs
Si la boucle d'événement de noeud agit comme une chaîne de bicyclette, l'observateur de collection côté serveur est comme un dérailleur. C'est un mécanisme d'engrenage qui va se retrouver sur la collecte de données à mesure que les données entrent en jeu. Il peut être très performant, car tous les vélos de course ont des dérailleurs. Mais c'est aussi une source de rupture de tout le système. C'est une fonction réactive à haute vitesse qui peut exploser sur vous. Être averti.
Meteor.startup(function(){
console.log('starting worker....');
var dataCursor = Posts.find({viewsCount: {$exists: true}},{limit:20});
var handle = dataCursor.observeChanges({
added: function (id, record) {
if(record.viewsCount > 10){
// run some statistics
calculateStatistics();
// or update a value
Posts.update({_id: id}, {$set:{
popular: true
}});
}
},
removed: function () {
console.log("Lost one.");
}
});
});
Notez que la limite de 20 est la taille du dérailleur .... combien de dents il a; ou, plus précisément, combien d’éléments se trouvent dans le curseur lorsqu’il parcourt la collection. Faites attention à l'utilisation du mot clé 'var' dans ce type de fonction. Écrivez le moins d'objets possible en mémoire et concentrez-vous sur la réutilisation des objets dans la méthode ajoutée. Lorsque le journal des opérations est activé, et que cette opération est en cours, il est un candidat idéal pour exposer les fuites de mémoire nuisibles si elle écrit des objets sur le tas de mémoire plus rapidement que le ramasse-miettes Node ne peut les nettoyer.
La solution ci-dessus ne sera pas bien mise à l'échelle car chaque instance Meteor essaiera de mettre à jour le même enregistrement. Donc, une sorte de détection de l'environnement est nécessaire pour que cela évolue horizontalement.
Voir le paquetage percolatestudios:synced-cron
pour un excellent exemple de synchronisation des travailleurs du service sur plusieurs machines d'un cluster.
météore-sync-cron