我正在尝试使用 MongoDB 来实现自然语言词典。我有一组词素,每个词素都有许多词形作为子文档。这是单个词素的样子:
{
"_id" : ObjectId("51ecff7ee36f2317c9000000"),
"pos" : "N",
"lemma" : "skrun",
"gloss" : "screw",
"wordforms" : [
{
"number" : "sg",
"surface_form" : "skrun",
"phonetic" : "ˈskruːn",
"gender" : "m"
},
{
"number" : "pl",
"surface_form" : "skrejjen",
"phonetic" : "'skrɛjjɛn",
"pattern" : "CCCVCCVC"
}
],
"source" : "Mayer2013"
}
目前我收集了大约 4000 个词位,每个词位平均有大约 1000 个词形的列表(而不是上面的 2 个)。这意味着我在集合中有 4,000,000 个独特的单词形式,我需要能够在合理的时间内搜索它们。
一个普通的查询应该是这样的:
db.lexemes.find({"wordforms.surface_form":"skrejjen"})
我在 上有一个索引wordforms.surface_form
,而且这个搜索非常快。但是,如果我想在搜索中使用通配符,则性能非常糟糕。例如:
db.lexemes.find({"wordforms.surface_form":/skrej/})
需要超过 5 分钟(此时我放弃了等待)。正如在这个问题中提到的,已知对索引进行正则表达式搜索是不好的。我知道在正则表达式搜索中添加 ^ 锚点有很大帮助,但它也严重限制了我的搜索能力。即使我愿意做出这种牺牲,我注意到响应时间仍然会因正则表达式而有很大差异。查询
db.lexemes.find({"wordforms.surface_form":/^s/})
需要 35 秒才能完成。
到目前为止,我得到的最好结果实际上是在我使用hint
. 在这种情况下,情况似乎有了很大改善。这个查询:
db.lexemes.find({"wordforms.surface_form":/skrej/}).hint('_id_')
大约需要 3 秒才能完成。
我的问题是,我还能做些什么来改善这些搜索时间吗?事实上,它们仍然有点慢,我已经在考虑迁移到 MySQL 以希望获得性能。但我真的很想保持 Mongo 的灵活性并避免 RDBMS 中所有繁琐的规范化。有什么建议么?您认为无论数据库引擎如何,使用这么多的文本数据,我都会遇到一些缓慢的问题吗?
我知道 Mongo 的新文本搜索功能,但它的优点(标记化和词干提取)与我的情况无关(更不用说不支持我的语言)。目前尚不清楚文本搜索是否实际上比使用正则表达式更快。