需要模式来动态搜索多个sql表
我正在寻找一种在多个表上执行动态搜索的模式。
我无法控制遗留(且设计不良)的数据库表结构。
考虑类似于简历搜索的场景,其中用户可能希望对简历中的任何数据执行搜索并获取与其搜索条件匹配的简历列表。 任何字段都可以随时与一个或多个其他字段组合进行搜索。
实际的 SQL 查询是根据搜索的字段动态创建的。 我发现的大多数解决方案都涉及复杂的 if 块,但我忍不住认为必须有一个更优雅的解决方案,因为现在这必须是一个已解决的问题。
是的,所以我开始走上在代码中动态构建 sql 的道路。 看起来很可怕。 如果我真的尝试支持所请求的查询任何表中任何字段的任意组合的能力,这将是一组大量的 if 语句。 颤抖
我相信我读到 COALESCE 仅在您的数据不包含 NULL 时才有效。 那是对的吗? 如果是这样,就不要去,因为我到处都有 NULL 值。
I'm looking for a pattern for performing a dynamic search on multiple tables.
I have no control over the legacy (and poorly designed) database table structure.
Consider a scenario similar to a resume search where a user may want to perform a search against any of the data in the resume and get back a list of resumes that match their search criteria. Any field can be searched at anytime and in combination with one or more other fields.
The actual sql query gets created dynamically depending on which fields are searched. Most solutions I've found involve complicated if blocks, but I can't help but think there must be a more elegant solution since this must be a solved problem by now.
Yeah, so I've started down the path of dynamically building the sql in code. Seems godawful. If I really try to support the requested ability to query any combination of any field in any table this is going to be one MASSIVE set of if statements. shiver
I believe I read that COALESCE only works if your data does not contain NULLs. Is that correct? If so, no go, since I have NULL values all over the place.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
据我了解(我也是一个针对可怕的遗留数据库编写过的人),不存在动态 WHERE 子句之类的东西。 它尚未解决。
就我个人而言,我更喜欢在代码中生成动态搜索。 使测试变得方便。 请注意,当您在代码中创建 SQL 查询时,不要在用户输入中连接。 使用你的@变量!
唯一的选择是使用 COALESCE 运算符。 假设您有下表:
并且您想要选择性地搜索姓名或昵称。 以下查询将执行此操作:
如果您不想搜索某些内容,只需传入 null。 例如,为@name 传入“brian”,为@nick 传入null 会导致对以下查询进行求值:
合并运算符将null 转换为恒等求值,该求值始终为真并且不会影响where 子句。
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:
and you want to search optionally for name or nickname. The following query will do this:
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:
The coalesce operator turns the null into an identity evaluation, which is always true and doesn't affect the where clause.
搜索和规范化可能相互矛盾。 因此,第一件事可能是获得某种“视图”,显示可以用单个键作为单行搜索的所有字段,从而获得简历。 然后你可以在前面添加类似 Lucene 的内容,为你提供全文索引这些行的工作方式是,您在此视图中询问“x”,它会将密钥返回给您。 这是一个很好的解决方案,乔尔本人在前 2 个月的 IIRC 播客中推荐了它。
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.
您需要的是 SphinxSearch (对于 MySQL)或 Apache Lucene。
正如您在示例中所说,让我们想象一份由多个字段组成的简历:
使用 WHERE 在所有这些字段中搜索单词很快就会变成一个包含多个 JOINS 的非常长的查询。
相反,您可以更改参考框架,并将整个简历视为单个文档,而您只想搜索该文档。
这就是 Sphinx 搜索等工具的作用。 他们创建您的“文档”的全文索引,然后您可以查询 sphinx,它会告诉您在数据库中找到该记录的位置。
确实很好的搜索结果。
不用担心该工具不是您的 RDBMS 的一部分,对于该应用程序,使用适当的模型“文档”而不是不正确的“表”将为您省去很多麻烦。
What you need is something like SphinxSearch (for MySQL) or Apache Lucene.
As you said in your example lets imagine a Resume that will composed of several fields:
So searching for a word in all those fields with WHERE rapidly becomes a very long query with several JOINS.
Instead you could change your framework of reference and think of the Whole resume as what it is a Single Document and you just want to search said document.
This is where tools like Sphinx Search do. They create a FULL TEXT index of your 'document' and then you can query sphinx and it will give you back where in the Database that record was found.
Really good search results.
Don't worry about this tools not being part of your RDBMS it will save you a lot of headaches to use the appropriate model "Documents" vs the incorrect one "TABLES" for this application.