Szukaj…
Uwagi
Przydatnym sposobem myślenia o kolekcjach Mongo jest określenie: kto, co, kiedy, gdzie, dlaczego i jak. Mongo ma następujące optymalizacje dla różnych typów danych:
Gdzie - GeoJSON
Kiedy - znaczniki czasu ObjectID
Kto - ciągi kont Meteor
Jak - JSON dla drzew decyzyjnych
Co pozostawia domyślny dokument w Mongo z grubsza reprezentujący „Co”.
Tworzenie rekordów w starszej bazie danych
Możesz ustawić domyślny format Mongo, definiując swoje kolekcje za pomocą pola idGeneration.
MyCollection = new Meteor.Collection('mycollection', {idGeneration : 'MONGO'});
Wstawianie danych do dokumentu
Wielu początkujących Mongo zmaga się z podstawami, takimi jak wstawianie tablicy, daty, wartości logicznej, zmiennej sesji itp. Do rekordu dokumentu. Ten przykład zawiera pewne wskazówki dotyczące podstawowych danych wejściowych.
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
});
Uzyskiwanie _id ostatnio utworzonego dokumentu
Możesz uzyskać to synchronicznie:
var docId = Todos.insert({text: 'foo'});
console.log(docId);
Lub asynchronicznie:
Todos.insert({text: 'foo'}, function(error, docId){
console.log(docId);
});
Dane szeregów czasowych
Używanie MongoDB do danych szeregów czasowych jest bardzo dobrze udokumentowanym i ustalonym przypadkiem użycia, z oficjalnymi dokumentami i prezentacjami. Przeczytaj i obejrzyj oficjalną dokumentację MongoDB, zanim spróbujesz wymyślić własne schematy dla danych szeregów czasowych.
MongoDB dla danych szeregów czasowych
Ogólnie rzecz biorąc, będziesz chciał utworzyć „segmenty” dla swoich danych szeregów czasowych:
DailyStats.insert({
"date" : moment().format("MM-DD-YYYY"),
"dateIncrement" : moment().format("YYYYMMDD"),
"dailyTotal" : 0,
'bucketA': 0,
'bucketB': 0,
'bucketC': 0
});
Następnie zwiększaj te segmenty jako źródła danych do aplikacji. Przyrost ten można wprowadzić w metodzie Meteor, obserwatorze kolekcji, punkcie końcowym interfejsu API REST i różnych innych miejscach.
DailyStats.update({_id: doc._id}, {$inc: {bucketA: 1} });
Aby uzyskać pełniejszy przykład Meteora, zobacz przykłady z toru Clinical Meteor:
Rurociąg analizy w czasie rzeczywistym
Meteor kliniczny - wykresy - Dailystats
Filtrowanie za pomocą Regexes
Prosty wzorzec do filtrowania subskrypcji na serwerze przy użyciu wyrażeń regularnych, zmiennych sesji reaktywnych i depresji autoruns.
// 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});
});
});
I HTML, który jest używany na kliencie:
<input id="dictionarySearchInput" type="text" placeholder="Filter..." value="hello"></input>
Ten wzór sam w sobie jest dość prosty, ale wyrażenia regularne mogą nie być. Jeśli nie znasz wyrażeń regularnych, oto kilka przydatnych samouczków i linków:
Samouczek wyrażeń regularnych
Ściągawka do wyrażeń regularnych
Wyrażenia regularne w JavaScript
Kolekcje geoprzestrzenne - Dowiedz się więcej
Zbiory geoprzestrzennych ogólnie obejmują przechowywanie GeoJSON w bazie Mongo, streaming, że dane do klienta, dostępu do przeglądarki window.navigator.geolocation
, załadunku API Map, konwersja GeoJSON do LatLngs i kreślenia na mapie. Najlepiej wszystko w czasie rzeczywistym. Oto lista zasobów na początek:
- mongodb optymalnie przechowuje swoje dane w geoJSON
- geojson.org
- window.navigator.geolocation
- Geolokalizacja HTML
- Wybór interfejsu API Map Google
- google.maps.LatLng
- Google map.data.loadGeoJson
- meteor-cordova-geolokalizacja-tło
- phonegap-googlemaps-plugin
- LatLng
- mapy.dokumentacja
- google.maps.LatLng
- Indeksy 2dsphere
- utwórz indeks 2dsphere
- zapytanie o indeks 2dsphere
- indeksy i zapytania geoprzestrzenne
Inspekcja zapytań dotyczących kolekcji
Poniższy przykład rejestruje wszystkie zapytania dotyczące kolekcji w konsoli serwera w czasie rzeczywistym.
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);
}
}
);
Funkcje obserwatorów i pracowników
Jeśli pętla zdarzeń Node działa jak łańcuch rowerowy, obserwator kolekcji po stronie serwera jest jak przerzutka. Jest to mechanizm zmiany biegów, który będzie siedział na gromadzeniu danych, gdy tylko dane wejdą. Może być bardzo wydajny, ponieważ wszystkie rowery wyścigowe mają przerzutki. Ale jest także źródłem zepsucia całego systemu. Jest to funkcja reaktywna przy dużej prędkości, która może cię wysadzić. Być ostrzeżonym.
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.");
}
});
});
Zwróć uwagę, że limit 20 to rozmiar przerzutki .... ile ma zębów; lub dokładniej, ile elementów znajduje się w kursorze, gdy chodzi po kolekcji. Uważaj przy użyciu słowa kluczowego „var” w tego rodzaju funkcji. Zapisz jak najmniej obiektów do pamięci i skup się na ponownym użyciu obiektu w dodanej metodzie. Kiedy opslog jest włączony, a ta rzecz nabiera pełnej prędkości, jest głównym kandydatem do ujawnienia nieprzyjemnych wycieków pamięci, jeśli zapisuje obiekty na stosie pamięci szybciej, niż kolektor śmieci Node jest w stanie wszystko wyczyścić.
Powyższe rozwiązanie nie będzie dobrze skalować w poziomie, ponieważ każda instancja Meteora będzie próbowała zaktualizować ten sam rekord. Aby skalować się w poziomie, konieczne jest wykrycie pewnego rodzaju środowiska.
Zobacz pakiet percolatestudios:synced-cron
, aby uzyskać doskonały przykład synchronizacji pracowników usług na wielu komputerach w klastrze.
meteor-synchronizowany-cron