2016-01-07 29 views
11

Sto lavorando a un sito creato in KeystoneJS che consente agli utenti di pubblicare parole e ottenere sinonimi suggeriti da altri utenti. Le parole sono presentate come parte di una frase o frase, come "Il gatto era [pericolosamente] vicino a bussare sul vetro".Come creare chiavi univoche in KeystoneJS

Il mio modello Frase assomiglia a questo:

Sentence.add({ 
    sentence: { type: Types.Text, required: true, initial: "New Sentence", index: true }, 
    word: { type: Types.Relationship, ref: 'Word', required: true, index: true, unique: true, initial: true }, 
    submitter: { type: Types.Relationship, ref: 'User', required: true, index: true, unique: true, initial: true }, 
    source: { type: Types.Text }, 
    createdAt: { type: Date, default: Date.now } 
}); 

e ho cercato di fare il modello di Word unica in base alla documentazione Mongoose:

var Word = new keystone.List('Word', { 
    map: { name: 'word' }, 
    _id: { from: 'word', path: 'word', unique: true, fixed: false} 
}); 

Word.add({ 
    word: { type: Types.Text, required: true, initial: "New word", index: true } 
}); 

Ma se io provarlo presentando due frasi con il stessa parola, fa solo una seconda istanza di quella parola con _id [parola] -1, [parola] -2, ecc.

Devo essere in grado di interrogare tutte le frasi che usano una particolare parola, quindi iodavvero bisogno di un oggetto per parola Ma per la vita di me, non riesco a capire come rendere un campo unico.

E 'possibile il mio problema è con quando aggiungo una nuova parola dal percorso responsabile di accettare le richieste AJAX:

var newWord = new Word.model({ 
    word: req.body.word // read from the input box on the home page 
}); 

newWord.save(function(err) { 
    if (err) { 
     console.error(err); 
    } 
}); 

Ma ho pensato .save sarebbe solo aggiornare un campo univoco esistente?

risposta

3

ero solo in grado di far rispettare l'unicità utilizzando il modulo mongoose-unique-validator in questo modo:

var keystone = require('keystone'); 
var Types = keystone.Field.Types; 
var uniqueValidator = require('mongoose-unique-validator'); 

var Word = new keystone.List('Word', { 
    map: { name: 'word' } 
}); 

Word.add({ 
    word: { type: Types.Text, index: true, unique: true } 
}); 

Word.schema.plugin(uniqueValidator); 

Word.defaultColumns = 'word'; 

Word.register(); 
3

è necessario cambiare il metodo add del modello come questo:

Word.add({ 
    word: { type: Types.Text, required: true, initial: "New word", index: true, unique: true } 
}); 

ho provato e ha lavorato per me, notare ho aggiunto unico: vero

ho creato un progetto chiave di volta utilizzando generatore di chiave di volta di Yeoman, e ha creato un modello di come la tua (lo si può trovare nel modello/test.js), quindi nella pagina di amministrazione quando provo ad aggiungere la stessa parola due volte ottengo:

Error saving changes to Word 569b98f27b5786db1c367b7a: 
{ [MongoError: E11000 duplicate key error collection: test_unique_field.words index: word_1 dup key: { : "test" }] 
    name: 'MongoError', 
    code: 11000, 
    err: 'E11000 duplicate key error collection: test_unique_field.words index: word_1 dup key: { : "test" }' } 

Questo è il link per il repo, se si vuole giocare con lui: keystonejs_test_unique

+0

sto ancora ricevendo multipla voci per la stessa parola quando guardo direttamente il database di Mongo. Se aggiungo la stessa parola due volte, '_id' diventa" [parola] -1 ", anche con' {unique: true} 'nel modello. Sto anche vedendo questo errore: '{[CastError: Cast to ObjectId failed for value" {word: 'sleek'} "al percorso" word "]' –

+0

In realtà, 'Cast to ObjectId' non è correlato, ma anche se uso l'ObjectId predefinito per _id, l'impostazione 'unique: true' fa ancora una nuova voce –