2016-01-07 12 views
11

Pracuję na stronie zbudowanej w KeystoneJS, która pozwala użytkownikom wysyłać słowa i otrzymywać sugerowane synonimy od innych użytkowników. Słowa są przekazywane jako część frazy lub zdania, np. "Kot był [niebezpiecznie] blisko puka do szkła".Jak tworzyć unikalne klucze w KeystoneJS

Mój model Zdanie wygląda następująco:

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 } 
}); 

I starał się model Słowo wyjątkowy według docs 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 } 
}); 

Ale gdybym go przetestować składając dwa zdania z to samo słowo, po prostu tworzy drugą instancję tego słowa z _id [słowo] -1, [słowo] -2 itd.

Potrzebuję być w stanie zapytać wszystkie zdania, które używają określonego słowa, więc ja naprawdę potrzebujesz jednego przedmiotu na słowo. Ale w moim życiu nie mogę wymyślić, jak stworzyć wyjątkowe pole.

Jest możliwe, mój problem jest ze kiedy dodać nowe słowo z trasy odpowiedzialny za przyjęcie żądań 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); 
    } 
}); 

Myślałam .save po prostu zaktualizować istniejący unikalne pole?

Odpowiedz

3

byłem tylko w stanie wymusić unikalność za pomocą modułu mongoose-unique-validator tak:

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

trzeba zmienić metodę dodawania danego modelu takiego:

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

próbowałem go i pracował dla mnie zauważy i dodaje wyjątkowy: prawdziwy

I stworzył projekt trapezowego za pomocą Yeoman's keystone generator i utworzył model taki jak twój (możesz go znaleźć w modelu/Test.js), a następnie na stronie administratora, gdy próbuję dodać to samo słowo dwa razy, otrzymuję:

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" }' } 

to jest link do repo jeśli chcesz grać z nim: keystonejs_test_unique

+0

nadal jestem coraz wielokrotność wpisy dla tego samego słowa, gdy patrzę bezpośrednio na bazę danych Mongo. Jeśli dodaję to samo słowo dwa razy, '_id' staje się" [słowo] -1 ", nawet z' {unique: true} 'w modelu. Widzę również ten błąd: '{[CastError: Cast do ObjectId nie powiodło się dla wartości" {word: 'sleek'} "at path" word "]' –

+0

W rzeczywistości, "Cast to ObjectId" nie ma związku, ale nawet jeśli używam domyślnego ObjectID dla _id, ustawienie 'unique: true' nadal powoduje wprowadzenie nowego wpisu –