【发布时间】:2012-11-05 14:09:25
【问题描述】:
在我学习计算机科学的过程中,我接触了一些函数式语言,比如 Prolog,但现在我在过去 10 年里只做 C#、Ruby JavaScript 和 Java 等命令式语言。目前,我正在为一家在线商店创建一个全文搜索引擎,而且我已经走得很远了。但是偶然发现了一些函数式语言,比如 Clojure 的 Haskell,很明显,函数式范式更适合,而命令式的方式并不是这项工作的正确工具。
所以我们有大约 1000 万条记录的全文索引。每条记录基本上都包含一个单词出现,以及它起源的记录的 id 和文本位置。
当用户输入一个搜索字符串时,它会被解析成一个表达式树。例如,搜索字符串“transformer 100 W”的结果类似于
AND('transformer%', OR(NEAR('100', 'W'), NEAR('100', 'watts'), '100W', '0.1kW'))
这里有一些额外的“智能”,但这与这个问题无关。
然后递归地评估表达式树,并产生几个 sql 查询,这些查询可以以 .NET-DataTables 的形式返回多达 100,000 行。然后将它们读入集合或字典,并根据谓词应用交集和并集,以找到与整个搜索表达式匹配的所有结果。对于 NEAR 评估,还比较了已发现事件的位置索引。但这都是命令式完成的,有很多 for 循环。
此外,还有一个排名功能,可以将找到的单词出现的分数相加。仅作为前缀或模糊匹配(由数据库服务器完成)找到的单词得分低于精确匹配。
对于每个结果项,我还需要获取所有匹配的单词的列表,以便在结果页面中突出显示这些单词。
所以大致评估算法是一个类似的函数
expression tree, full text index ->
resulting items that match the expressin tree,
each with a ranking sum
and a list of all found word occurrences for this item
我只是在这里给出一个粗略的概述,但我希望你能得到足够的图片。
现在是“现实世界”的约束:
- 整个应用程序(到目前为止)都是用 C# 编写的,因此与 .NET 的轻松集成至关重要。
- 大量数据被读入 .NET-DataTables,然后需要进行评估和转换。结果应包含在 .NET 类型中(字典、集合、数组等...)。
- 性能非常重要。目前我的算法搜索通常需要两秒钟(不包括 sql),这还可以,但应该改进。我们的服务器有 16 个处理器,因此欢迎并行处理。由于我们每秒收到一个搜索请求,并且当前实现是单线程的,因此处理器时间仍然可用。
- 语言(和编译器)应该是成熟的。
因为我需要继续使用 .NET,所以我一直在研究 Clojure-CLR、F# 和 Scala 的 .NET。
我非常喜欢 Clojure 的概念,但现在我无法评估它是否能胜任这项工作。阅读有关 F# 的文章让我感觉很复杂,因为它似乎希望能够做几乎所有事情,而对于给定的任务,我倾向于使用更“纯”的数学方法。但也许这对于 F# 也是可能的,我还没有意识到这一点。我还没有深入研究 Scala,但它似乎已经很成熟了。
欢迎任何见解!
【问题讨论】:
-
这里根本帮不了你,但是...... Prolog 通常不被认为是一种函数式语言,而是一种逻辑编程语言,或者一种演绎语言。
-
C#、Ruby、JavaScript 是函数式语言。序言不是。我怀疑,LINQ(也非常实用)在你的情况下应该足够了。
-
C#、Ruby 和 JavaScript 不是函数式语言。它们是支持一些函数抽象的语言,但对函数式编程的语言支持很少。
-
@SK-logic,所以all of these are functional(包括Java和C)?
-
大家好,您可以考虑在函数式语言讨论中打开一个单独的线程。在这里,它基本上使我的问题的答案难以讨论。感谢 Dax 分享您的见解并直言不讳!
标签: .net scala haskell clojure f#