2012-04-16 9 views
26

Sto provando a creare un indice univoco di due colonne sul mongodb sottostante in un'app di meteor e che presenta problemi. Non riesco a trovare nulla nei documenti meteo. Ho provato dalla console cromata. Ho provato dal termine e ho anche provato a puntare mongod nella directory/db/dir all'interno di .meteor. Ho provatoCome posso aggiungere un id univoco a due colonne a mongodb in un'app meteorica?

Collection.ensureIndex({first_id: 1, another_id: 1}, {unique: true}); variazioni.

Desidero essere in grado di impedire le voci duplicate su una raccolta di Mongo app meteorica.

Chiedersi se qualcuno l'ha capito?

Ho risposto alla mia domanda, che noob.

L'ho capito.

  1. Inizio meteora del server

  2. Aprire secondo terminale e digitare meteor mongo

quindi creare l'indice ... per esempio ho fatto questi per i record di thumbsup e thumbsdown tipo di sistema.

db.thumbsup.ensureIndex({item_id: 1, user_id: 1}, {unique: true}) 
db.thumbsdown.ensureIndex({item_id: 1, user_id: 1}, {unique: true}) 

Ora, proprio la figura devo un bootstrap installazione di installazione che crea questi quando spinto a spingere invece che manualmente.

+1

Ho postato la mia risposta prima di vedere la modifica, ma osservando che solo abilitando l'indicizzazione sul lato server gli utenti penseranno che stanno dando più upvotes anche se questi non vengono effettivamente salvati. Quindi probabilmente è meglio anche eseguire una query prima di inserirla come soluzione alternativa. – danny

+3

Sarebbe meglio se pubblichi la tua risposta separatamente dalla domanda. È più leggibile – zVictor

risposta

15

Secondo il numero docs "Attualmente il Minimongo non ha indici, ma arriverà presto." E guardando i metodi disponibili su una collezione, non c'è ensureIndex.

È possibile eseguire meteor mongo per una shell mongo e abilitare gli indici sul lato server, ma l'oggetto Collection ancora non ne saprà nulla. Quindi l'app ti consentirà di aggiungere più istanze alla cache della raccolta, mentre sul lato server gli inserimenti aggiuntivi non funzioneranno automaticamente (gli errori vengono scritti nell'output). Quando si esegue un aggiornamento della pagina difficile, l'applicazione sarà ri-sincronizzazione con il server

Quindi la soluzione migliore per ora è probabilmente quello di fare qualcosa di simile:

var count = MyCollection.find({first_id: 'foo', another_id: 'bar'}).count() 
if (count === 0) 
    MyCollection.insert({first_id: 'foo', another_id: 'bar'}); 

che ovviamente non è l'ideale, ma funziona bene. Puoi anche abilitare l'indicizzazione in mongodb sul server, quindi anche nel caso di una race condition non otterrai effettivamente record duplicati.

+0

Grazie @danny, stavo proprio notando questo comportamento quando è arrivato questo post. –

+0

BTW, per chiunque mi chiedesse, ho implementato entrambi. La logica di cui sopra sul front-end e un indice univoco sul back-end per sicurezza e sanità mentale. –

+3

questa soluzione non sembra ancora ideale .. cosa succede se chiami 'MyCollection.find' prima che l'app abbia estratto tutti i dati dal server? – Lloyd

1

realtà perché non utilizzare upsert sul server con un Meteor.method e si potrebbe anche inviare anche seguirli con un ts: // Server Solo

Meteor.methods({ 
add_only_once = function(id1,id2){ 
    SomeCollection.update(
    {first_id:id1,another_id:id2},{$set:{ts:Date.now()}},{upsert:True}); 
} 
}); 

// client

Meteor.call('add_only_once',doc1._id, doc2._id); 

// codice effettivo in esecuzione sul server

if(Meteor.is_server) { 
    Meteor.methods({ 
     register_code: function (key,monitor) { 
      Codes.update({key:key},{$set:{ts:Date.now()}},{upsert:true}); 
     } 
    ... 
+1

Secondo docs.meteor.com upsert non è ancora supportato con roba Mongo/MiniMongo. Altrimenti sarebbe bello. –

+0

Ho funzionato sul server, basato su un singolo id/chiave. – limeyd

+0

upsert funziona? ottime notizie che il codice funziona ora forse le ultime versioni di Meteor hanno risolto questo problema? Non saprei, non ho usato Meteor in un paio di settimane. –

31

Raccolta._ensureIndex (indice, opzioni)

Ricerca all'interno del codice sorgente Meteor, ho trovato un binding a ensureIndex chiamato _ensureIndex. Per gli indici di base a semplice tasto è possibile seguire l'esempio di packages/accounts-base/accounts_server.js che costringe nomi utente univoci su Meteor:

Meteor.users._ensureIndex('username', {unique: 1, sparse: 1}); 

per il multi-key "composti" indici:

Collection._ensureIndex({first_id:1, another_id:1}, {unique: 1}); 

codice precedente, quando sono immessi sul lato server, assicura che gli indici siano impostati.

Attenzione

avvertenza implementazione _ensureIndex:

Ci troveremo a progettare un'API di indice più tardi. Per ora, passiamo semplicemente da a quello di Mongo, ma rendiamolo sincrono.

+0

Qualsiasi idea su che cosa significa "spazio: 1"? –

3

Lo Smartpackage aldeed:collection2 supporta indici univoci, oltre alla convalida dello schema. La convalida avverrà sia sul server che sul client (in modo reattivo), in modo che tu possa reagire agli errori sul client.

+1

Ma non è possibile utilizzarlo per creare indici composti: https://github.com/aldeed/meteor-collection2#index-and-unique –

Problemi correlati