如何在 KeystoneJS 中创建唯一键
How to create unique keys in KeystoneJS
我正在开发一个使用 KeystoneJS 构建的网站,该网站允许用户使用 post 个词并从其他用户那里获得建议的同义词。单词作为短语或句子的一部分提交,例如 "The cat was [perilously] close to knocking over the glass."
我的句子模型如下所示:
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 }
});
并且我尝试根据 Mongoose 文档使 Word 模型独一无二:
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 }
});
但是如果我通过提交两个包含同一个词的句子来测试它,它只会使用_id [word]-1、[word]-2 等生成该词的第二个实例。
我需要能够查询所有使用特定词的句子,所以我真的需要每个词一个项目。但是对于我的生活,我无法弄清楚如何使一个领域独一无二。
我的问题可能出在我从负责接受 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);
}
});
但我认为 .save
只会更新现有的唯一字段?
您需要像这样更改模型的添加方法:
Word.add({
word: { type: Types.Text, required: true, initial: "New word", index: true, unique: true }
});
我试过了并且对我有用,注意我添加了 unique:true
我使用 yeoman 的 keystone 生成器创建了一个 keystone 项目,并创建了一个像您一样的模型(您可以在 model/Test.js 中找到它),然后在管理页面中尝试添加相同的单词两次我得到:
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" }' }
这是 link 回购协议,如果你想玩的话:keystonejs_test_unique
我只能通过使用 mongoose-unique-validator 模块来强制执行唯一性,如下所示:
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();
我正在开发一个使用 KeystoneJS 构建的网站,该网站允许用户使用 post 个词并从其他用户那里获得建议的同义词。单词作为短语或句子的一部分提交,例如 "The cat was [perilously] close to knocking over the glass."
我的句子模型如下所示:
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 }
});
并且我尝试根据 Mongoose 文档使 Word 模型独一无二:
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 }
});
但是如果我通过提交两个包含同一个词的句子来测试它,它只会使用_id [word]-1、[word]-2 等生成该词的第二个实例。
我需要能够查询所有使用特定词的句子,所以我真的需要每个词一个项目。但是对于我的生活,我无法弄清楚如何使一个领域独一无二。
我的问题可能出在我从负责接受 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);
}
});
但我认为 .save
只会更新现有的唯一字段?
您需要像这样更改模型的添加方法:
Word.add({
word: { type: Types.Text, required: true, initial: "New word", index: true, unique: true }
});
我试过了并且对我有用,注意我添加了 unique:true
我使用 yeoman 的 keystone 生成器创建了一个 keystone 项目,并创建了一个像您一样的模型(您可以在 model/Test.js 中找到它),然后在管理页面中尝试添加相同的单词两次我得到:
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" }' }
这是 link 回购协议,如果你想玩的话:keystonejs_test_unique
我只能通过使用 mongoose-unique-validator 模块来强制执行唯一性,如下所示:
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();