检查数据库中是否存在每个单词

时间:2016-12-06 09:51:33

标签: javascript node.js mongodb meteor

问题

我需要通过搜索每个单词的mongoDB集合来检查字符串的每个单词是否拼写正确。

  1. 执行最少量的数据库查询
  2. 每个句子的第一个单词必须是大写,但这个单词可以是字典中的大写或小写。所以我需要对每个单词进行区分大小写的匹配。只有每个句子的第一个单词应该是 敏感。
  3. 示例字符串

    This is a simple example. Example. This is another example.
    

    字典结构

    假设有一个像这样的词典集合

    { word: 'this' },
    { word: 'is' },
    { word: 'a' },
    { word: 'example' },
    { word: 'Name' }
    

    就我而言,这本词典中有100,000个单词。当然,名称以大写形式存储,动词以小写形式存储,依此类推......

    预期结果

    单词simpleanother应该被识别为'拼错'字样,因为它们不存在于数据库中。

    在这种情况下,应包含所有现有单词的数组:['This', 'is', 'a', 'example']This是大写的,因为它是句子的第一个单词;在DB中,它存储为小写this

    到目前为止我的尝试(已更新)

    const   sentences   = string.replace(/([.?!])\s*(?= [A-Z])/g, '$1|').split('|');
    let     search      = [],
            words       = [],
            existing,
            missing;
    
    sentences.forEach(sentence => {
        const   w   = sentence.trim().replace(/[^a-zA-Z0-9äöüÄÖÜß ]/gi, '').split(' ');
    
        w.forEach((word, index) => {
            const regex = new RegExp(['^', word, '$'].join(''), index === 0 ? 'i' : '');
            search.push(regex);
            words.push(word);
        });
    });
    
    existing = Dictionary.find({
        word: { $in: search }
    }).map(obj => obj.word);
    
    missing = _.difference(words, existing);
    

    问题

    1. 不敏感的匹配无法正常运行:/^Example$/i会给我一个结果。但是在existing中会有原始的小写example,这意味着Example会转到missing - 数组。因此,不区分大小写的搜索按预期工作,但结果数组有一个不匹配。我不知道如何解决这个问题。
    2. 可能优化代码?因为我正在使用两个forEach - 循环和一个difference ...

1 个答案:

答案 0 :(得分:0)

这就是我面对这个问题的方法:

  • 使用正则表达式获取空格后的每个单词(包括'。')。

    var words = para.match(/(.+?)(\b)/g); //this expression is not perfect but will work
    
  • 现在使用find()将数据从集合中添加到数组中。假设该数组的名称是 wordsOfColl

  • 现在检查单词是否符合您的要求

    var prevWord= ""; //to check first word of sentence
    
    words.forEach(function(word) {
        if(wordsOfColl.toLowerCase().indexOf(word.toLowerCase()) !== -1) {
           if(prevWord.replace(/\s/g, '') === '.') {
              //this is first word of sentence
              if(word[0] !== word[0].toUpperCase()) {
                 //not capital, so generate error
              }
            } 
           prevWord = word;
         } else {
           //not in collection, generate error
         }
    });
    

我还没有测试过,所以如果有问题请在评论中告诉我。或者我错过了你的一些要求。

<强>更新

由于问题的作者建议他不想在客户端上加载整个集合,您可以在服务器上创建一个方法,该方法返回一个单词数组,而不是提供对集合客户端的访问。

相关问题