在包含json的文本字段中搜索

时间:2017-11-14 06:48:56

标签: mysql ruby-on-rails json

我的应用程序位于RoR,数据库位于MYSQL。我有User Table。它包含一个字段name。它的类型是文字。 它包含{"first_name"=> 'Allen', "last_name"=> 'PAul'}之类的值以及其他一些信息。

我可以使用store: accessors: [], coder: JSON将其存储在数据库中。

现在,我想要检索first_name =='Allen'的所有记录。那么如何在rails中实现这个目标

4 个答案:

答案 0 :(得分:1)

我认为您无法使用经典的ActiveRecord搜索JSON字段。

但是你可以执行raw sql:

编辑:您的姓名字段必须是json字段。

@users = ActiveRecord::Base.connection.execute("SELECT * FROM users WHERE JSON_SEARCH(name, 'all', '#{first_name_to_search}') IS NOT NULL;")

更多信息here

答案 1 :(得分:1)

希望这有效

User.where("name LIKE ?", , '%first_name: #{query}%')

答案 2 :(得分:1)

问题是用于表示json的实际文本表示......

使用

ActiveRecord::Base.connection.execute("SELECT * FROM users")

您可以看到如何构造LIKE子句以查找数据库中的实际文本表示。之后你可以使用

User.find_by_sql("SELECT * FROM users WHERE name LIKE ...") 

进行实际查询

答案 3 :(得分:0)

您使用ActiveRecord::Store重叠了name字段。来自文档:

  

Store为序列化提供了一个薄包装,用于在单个列中存储哈希值。这就像是一个简单的键/值存储,当您不关心能够在单个记录的上下文之外查询该商店时,它会记录在您的记录中。

您不能以您描述的方式使用该字段,并且尝试这样做违背了您正在使用的API的目的,因此我建议不要这样做。您有几种选择:

  1. 使用某种慢查询(SELECT * FROM User WHERE name LIKE '%foo%'
  2. 搜索字段
  3. 实例化所有记录,然后解析它们(User.all.map { |user| user.name.match(/foo/)
  4. 规范化您的数据库并为您要搜索的每个字段指定相应的字段(name拆分为first_namelast_name
  5. 在这三个选项中,只有 3 是正确的选择。其他两个可能有效但不应该使用,因为它将引入性能和可靠性问题。

    作为使用 3 的奖励,您可以创建一种方法来履行name的角色:

    class User < ActiveRecord::Base
      def name
        {
          first_name: first_name,
          last_name: last_name
        }
      end
    end
    

    然后,您可以按照自己的方式进行搜索:

    user = User.where(first_name: 'foo').first
    

    仍然返回名称:

    user.name
    => { first_name: 'foo', last_name: 'bar' }