I'm working on a site built in KeystoneJS that allows users to post words and get suggested synonyms from other users. Words are submitted as part of a phrase or sentence, like "The cat was [perilously] close to knocking over the glass."
My Sentence model looks like this:
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 }
});
And I tried to make the Word model unique according to Mongoose docs:
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 }
});
But if I test it by submitting two sentences with the same word, it just makes a second instance of that word with the _id [word]-1, [word]-2, etc.
I need to be able to query all sentences that use a particular word, so I really need one item per word. But for the life of me, I can't figure out how to make a field unique.
It's possible my problem is with when I add a new Word from the route responsible for accepting AJAX requests:
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);
}
});
But I thought .save
would just update an existing unique field?
I was only able to enforce the uniqueness by using the mongoose-unique-validator module like so:
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();