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

use*_*695 6 javascript mongodb node.js meteor

问题

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

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

样本字符串

This is a simple example. Example. This is another example.
Run Code Online (Sandbox Code Playgroud)

字典结构

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

{ word: 'this' },
{ word: 'is' },
{ word: 'a' },
{ word: 'example' },
{ word: 'Name' }
Run Code Online (Sandbox Code Playgroud)

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

预期结果

单词simpleanother应该被识别为"拼写错误"单词,因为它们不存在于DB中.

在这种情况下,包含所有现有单词的数组应该是:['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);
Run Code Online (Sandbox Code Playgroud)

问题

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

Muk*_*ain 0

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

  • 使用正则表达式获取数组中空格(包括“.”)后的每个单词。

    var words = para.match(/(.+?)(\b)/g); //this expression is not perfect but will work
    
    Run Code Online (Sandbox Code Playgroud)
  • 现在,使用 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
         }
    });
    
    Run Code Online (Sandbox Code Playgroud)

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

更新

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