7

我正在寻找一种在多个表上执行动态搜索的模式。

我无法控制遗留(且设计不佳)的数据库表结构。

考虑类似于简历搜索的场景,其中用户可能希望对简历中的任何数据执行搜索,并获取与其搜索条件匹配的简历列表。任何字段都可以随时与一个或多个其他字段组合进行搜索。

实际的 sql 查询是根据搜索的字段动态创建的。我发现的大多数解决方案都涉及复杂的 if 块,但我不禁认为必须有一个更优雅的解决方案,因为现在这必须是一个已解决的问题。


是的,所以我开始了在代码中动态构建 sql 的路径。看起来很可怕。如果我真的尝试支持查询任何表中任何字段的任何组合的请求能力,这将是一组 MASSIVE 语句。 颤抖


我相信我读到 COALESCE 仅在您的数据不包含 NULL 时才有效。那是对的吗?如果是这样,那就不行,因为我到处都有 NULL 值。

4

3 回答 3

5

As far as I understand (and I'm also someone who has written against a horrible legacy database), there is no such thing as dynamic WHERE clauses. It has NOT been solved.

Personally, I prefer to generate my dynamic searches in code. Makes testing convenient. Note, when you create your sql queries in code, don't concatenate in user input. Use your @variables!

The only alternative is to use the COALESCE operator. Let's say you have the following table:

Users
-----------
Name nvarchar(20)
Nickname nvarchar(10)

and you want to search optionally for name or nickname. The following query will do this:

SELECT Name, Nickname
FROM Users
WHERE
    Name = COALESCE(@name, Name) AND
    Nickname =  COALESCE(@nick, Nickname)

If you don't want to search for something, just pass in a null. For example, passing in "brian" for @name and null for @nick results in the following query being evaluated:

SELECT Name, Nickname
FROM Users
WHERE
    Name = 'brian' AND
    Nickname =  Nickname

The coalesce operator turns the null into an identity evaluation, which is always true and doesn't affect the where clause.

于 2008-08-13T14:29:36.487 回答
1

你需要的是像SphinxSearch (for MySQL) 或Apache Lucene这样的东西。

正如您在示例中所说,让我们想象一个由几个字段组成的简历:

  • 项目清单
  • 姓名,
  • 地址,
  • 教育(这可能是一张单独的桌子)或
  • 工作经验(这可能会增长到自己的表格,其中每一行代表以前的工作)

因此,使用 WHERE 在所有这些字段中搜索一个单词很快就会变成一个包含多个 JOINS 的非常长的查询。

相反,您可以更改您的参考框架并将整个简历视为单个文档,而您只想搜索该文档。

这就是 Sphinx Search 等工具的作用。他们为您的“文档”创建一个全文索引,然后您可以查询狮身人面像,它会告诉您在数据库中找到该记录的位置。

真的很好的搜索结果。

不要担心这个工具不是您的 RDBMS 的一部分,使用适当的模型“文档”与不正确的模型“表”用于此应用程序,它将为您省去很多麻烦。

于 2009-07-04T00:59:33.697 回答
1

Search and normalization can be at odds with each other. So probably first thing would be to get some kind of "view" that shows all the fields that can be searched as a single row with a single key getting you the resume. then you can throw something like Lucene in front of that to give you a full text index of those rows, the way that works is, you ask it for "x" in this view and it returns to you the key. Its a great solution and come recommended by joel himself on the podcast within the first 2 months IIRC.

于 2008-08-13T14:56:15.420 回答