【问题标题】:How to create unique keys in KeystoneJS如何在 KeystoneJS 中创建唯一键
【发布时间】:2016-04-12 10:50:49
【问题描述】:

我正在开发一个使用 KeystoneJS 构建的网站,该网站允许用户发布单词并从其他用户那里获得建议的同义词。单词作为短语或句子的一部分提交,例如“这只猫 [危险地] 差点打翻玻璃。”

我的 Sentence 模型如下所示:

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 请求的路由中添加新 Word 时,我的问题可能是:

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 只会更新现有的唯一字段?

【问题讨论】:

    标签: node.js mongodb mongoose keystonejs nosql


    【解决方案1】:

    您需要像这样更改模型的添加方法:

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

    如果你想玩它,这是 repo 的链接:keystonejs_test_unique

    【讨论】:

    • 当我直接查看 Mongo 数据库时,我仍然会收到同一个单词的多个条目。如果我两次添加相同的单词,_id 将变为“[word]-1”,即使模型中有 { unique: true }。我也看到了这个错误:{ [CastError: Cast to ObjectId failed for value "{ word: 'sleek' }" at path "word"]
    • 其实Cast to ObjectId是不相关的,但是即使我为_id使用默认的ObjectId,设置unique: true仍然是一个新条目
    【解决方案2】:

    我只能像这样使用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();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-09
      • 1970-01-01
      • 2013-04-12
      • 2020-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多