【问题标题】:How do I query a database field but ignore the HTML markup?如何查询数据库字段但忽略 HTML 标记?
【发布时间】:2011-01-15 20:15:32
【问题描述】:

我们有一个包含用于在网站上格式化的 HTML 标记的字段,但我们只需要查询应该在屏幕上呈现的文本,而不是 CSS 标记、标记名称、属性名称等内容。

有没有办法忽略 SQL 查询或存储过程中的标记?如果有办法做到这一点,我们以后会不会出现性能问题?

我的猜测是有某种方法可以使用尖括号来解析可搜索文本的字段。

【问题讨论】:

    标签: sql html search


    【解决方案1】:

    【讨论】:

    • 我在想像这样的函数会更难,但通读它让我意识到假设我有良好的 HTML 格式,这应该总是有效的。我们现在正在对此进行测试。谢谢!
    • 每次你尝试用正则表达式解析 HTML 时,上帝都会杀死一只小猫。
    • 幸运的是没有涉及到正则表达式:)
    • 虽然解析包含 HTML 的字段永远不会完美,但这个简单的函数几乎总是可以完美运行。非常感谢!
    【解决方案2】:

    这样的处理不应该在数据库中进行。我建议创建一个仅包含文本内容的单独字段。

    回应@Nissan Fans 评论:从 HTML 中提取文本不是 IMO 数据库的工作。它的工作太复杂了,它有太多的变数。我不精通阅读存储过程,但如果我正确阅读代码,它会在源代码中出现(无效但仍经常发生)未编码的< 的问题。而且它很可能会因为无效的 HTML 而中断。

    或者想象有一天,客户来了,并希望 img 元素的 ALT 属性也被索引。或titles。使用“开始位置,结束位置”算法开始构建它。你会发疯

    我说,如果需要在日常基础上处理来自您无法控制的不同来源的 HTML,请将其留给 DB 之上的层,以便更好地处理这些东西。基于 DOM 的方法——也许使用 BeautifulSoup 来处理无效的 HTML——解析所有 nodeValues 将是最可靠的方法。

    也许这是矫枉过正,存储过程在 OP 的情况下可以正常工作 - 从他的评论中看起来很像,这完全没问题。我只是说,如果您无法控制传入的 HTML,请不要使用数据库为这项工作提供的有限手段来剥离 HTML。

    【讨论】:

    • 复制数据,因为您必须查询它的子集,这似乎是不规则的。这就像将日期分解为每个组件,因为有人只想查询月份。如果这不是一个超大规模的数据库,那应该不是问题。
    • 这个思路不错,每次查询都去掉html肯定很慢。
    • 用于存储相同信息的空间也增加了一倍。还有很多其他的事情需要考虑......也许这个搜索是每 5,000 次有人使用 HTML 数据就使用一次的功能?想象一个应用程序显示带有标签的数据列表,但允许进行文本搜索,如果每次都使用的话。没有足够的背景来证明这一点。此外,我的不同意与他关于单独字段的陈述无关,而更多地与这样一个事实有关,即查询这样的数据正是数据库的用途。
    • @Nissan Fan,你的观点是正确的。不过,在这种情况下,我认为数据库不适合这样做。请参阅我的更新答案。
    • 我认为你是绝对正确的,这是对数据库施加的过于复杂的处理。如果我搜索更多行,如果这些行的内容比它们更重要,我会这样做。在我的情况下,虽然这是一个包含可疑数据的描述字段,但在我们测试了一个简单的函数后,观察括号一切正常。因此,您会为此答案获得 +1,但我们使用了 @Nissan Fan 链接的简单函数。
    【解决方案3】:

    我同意 Pekka 的观点;这不是您的数据库应该处理的事情。

    在数据库中进行这种解析的缺点:

    1. 性能问题。使用 UDF 会降低性能并导致表扫描。即使你避免了表扫描,你仍然要求数据库做一堆它不是设计要做的事情(字符串操作)。

    2. 更难做到正确。正确解析 HTML 是一项艰巨的工作。确实,您可以使用 UDF 完成 95% 的工作,但在应用程序层处理此问题可能会让您完成 100% 的工作。

    3. 更难测试。我更愿意为在 C# 中针对字符串文字执行的 HTML 剥离代码编写单元测试,而不是往返于数据库。

    如果您必须在数据库中执行此操作...

    如果需要在数据库中执行此操作,请考虑以下方法:

    1. 向您的数据库添加第二个字段以保存内容的纯文本版本。

    2. 添加触发器,以便每次更改 HTML 值时,都会重新生成文本版本。

    3. 针对纯文本字段编写查询。

    您将获得更好的性能,因为您只在写入时进行解析,而不是在每次搜索时进行,并且您的数据库将更好地利用您在纯文本字段中定义的任何索引。

    【讨论】:

      【解决方案4】:

      如果您可以在查询中运行正则表达式,则可以使用此处的示例去除 HTML 并仅返回文本:http://www.regular-expressions.info/examples.html

      【讨论】:

        【解决方案5】:

        如果您尝试索引这些列之一并通过删除 html 来访问它:

        WHERE dbo.anyRemoveHtml(yourColumn)='your search text'
        

        不会使用索引,您将进行表扫描。当应用程序的数据很少时,这可能不是问题,但随着向表中添加更多数据,会导致 SELECT 越来越慢。

        注意:dbo.anyRemoveHtml 只是一个虚构的名称,代表您选择删除 HTML 的函数,实际上并不存在

        【讨论】:

          猜你喜欢
          • 2021-09-02
          • 1970-01-01
          • 2014-12-24
          • 2017-07-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多