【问题标题】:Database design that requires two searches需要两次搜索的数据库设计
【发布时间】:2020-04-09 17:27:24
【问题描述】:

我过去玩过 mongodb,但这是我第一次从事项目。

我正在设计一本西班牙语词典。但是我在设计上遇到了麻烦。这是第一个设计。这些是存储在 mongodb 中的对象。

字典合集

{
    word:"comer",
    type:"infinitive",
   Definition:"A definiition for the word hablar",
    conjugation: {
        present: ["como", "comes", "come", "comemos", "coméis", "comen"],
        preterite:["comí", "comiste", "comió", "comimos", "comisteis", "comieron"],
    }
},
// Lets pretend that this is another verb with different conjugation forms.
{
    word:"hablar",
    type:"infinitive",
   Definition:"A definiition for the word hablar",
    conjugation: {
        present: ["como", "comes", "come", "comemos", "coméis", "comen"],
        preterite:["comí", "comiste", "comió", "comimos", "comisteis", "comieron"],
    }
}

通过这种设计,我可以通过比较 word:"a word" 属性来搜索单词。问题在于,在这种设计中搜索“como”是不可行的,或者至少效率不高。

第二种设计有两个集合Wordsverbs

单词

{
    word:"como",
    infinitive:"comer",
},
{
    word:"comer",
    infinitive:"comer",
},
{
    word:"comemos",
    infinitive:"comer",
},
{
    word:"habla",
    infinitive:"hablar",
}

动词

{
    word:"comer",
    Definition:"A definiition for the word comer",
    conjugation: {
        present: ["como", "comes", "come", "comemos", "coméis", "comen"],
        preterite:["comí", "comiste", "comió", "comimos", "comisteis", "comieron"],
    }
},
{
    word:"hablar",
    Definition:"A definiition for the word hablar",
    conjugation: {
        present: ["como", "comes", "come", "comemos", "coméis", "comen"],
        preterite:["comí", "comiste", "comió", "comimos", "comisteis", "comieron"],
    }
}

通过这种设计,可以轻松搜索任何单词。然后可以使用 infinitive 属性来搜索 Verbs 集合。

现在的问题是需要两次搜索才能找到一个单词。更糟糕的是,要找到像单词 comer 这样的不定式,您首先要搜索 words 集合以找到相同的单词 comer,然后再查找它在动词集合中。

问题

必须执行两次搜索才能找到一个单词是否不寻常?

这是一个糟糕的设计还是可以改进?

我可以设计成只需要一次搜索吗?

注意:

我了解数据可以存储在多个集合中,因此可能需要进行多次搜索。但这是不同的,因为必须先进行一次搜索,然后再搜索多个集合以获取我们需要的信息。

【问题讨论】:

  • 对于 first 设计,您为什么认为 "... 问题在于,在这种设计中搜索“como”是不可能的,或者至少不可能高效。” 您是否尝试过任何查询或在集合上创建任何索引?最常用的查询可能是什么样的?
  • 您可以通过第一个“设计”轻松高效地搜索“como”为dictionary.find({$or: [{word: "como"}, {"conjugation.present": "como"}, {"conjugation.preterite": "como"}]})
  • @Prasad 可以有许多同名的单词,据我了解,在这些情况下不建议使用索引。还是我误解了索引的工作方式?
  • “可以有很多同名的词,我的理解是在这些情况下不建议使用索引。” 是的,可以有很多同名的词姓名;但是,索引是为了高效或快速搜索。

标签: node.js json mongodb database-design


【解决方案1】:

请查看下面的链接以了解如何在 MongoDB https://docs.mongodb.com/manual/tutorial/query-arrays/ 中查询数组。

【讨论】:

    【解决方案2】:

    您可以使用 MongoDB 的 Text Search 功能进行您的第一个设计。

    首先我们在要搜索的字段上创建一个复合索引:

    db.dictionaries.createIndex(
       {
         "word": "text",
         "conjugation.present": "text",
         "conjugation.preterite": "text"
       }
     )
    

    然后我们可以像这样使用 $text 查询运算符:

    db.dictionaries.find(
        { $text: { $search: "comen" } },
        { score: { $meta: "textScore" } }
      ).sort({ score: { $meta: "textScore" } });
    

    $text 将使用空格和大多数标点符号作为分隔符对搜索字符串进行标记,并对搜索字符串中的所有此类标记执行逻辑或。

    假设您在集合中有这些文档:

    [
      {
        "_id": ObjectId("5df8bb67646b812758d7e6c5"),
        "conjugation": {
          "present": [ "como", "comes", "come", "comemos", "coméis", "comen" ],
          "preterite": [ "comí", "comiste", "comió", "comimos", "comisteis", "comieron" ]
        },
        "word": "comer",
        "type": "infinitive",
        "definition": "A definition for the word comer"
      },
      {
        "_id": ObjectId("5df8bb9f646b812758d7e6c6"),
        "conjugation": {
          "present": [ "como", "comes", "come", "comemos", "coméis", "comen" ],
          "preterite": [ "comí", "comiste", "comió", "comimos", "comisteis", "comieron" ]
        },
        "word": "hablar",
        "type": "infinitive",
        "definition": "A definition for the word hablar"
      }
    ]
    

    当我们按“comer”搜索时,只会找到第一个文档。

    当我们通过“hablar”搜索时,只会找到第二个文档。

    当我们通过“como”搜索时,两个文档都会被找到。

    您甚至可以为文本索引指定 language,西班牙语是支持的语言之一。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-22
      • 2010-11-09
      • 2014-10-22
      • 1970-01-01
      • 2023-03-24
      相关资源
      最近更新 更多