搜刮Mysql的JSON字段的值

打印 上一主题 下一主题

主题 887|帖子 887|积分 2661

我们在查询mysql数据时,查询某个字段的数剧是我们常常打仗的,直接利用sql语句或者更方便的直接利用数据库的orm语句查询。但是假如必要查询某个json字段里面的某些数据,orm模型大概都无法达到结果,还不如直接利用sql语句举行查询来的直观。下面总结了一些sql语句查询json字段里面的值。
mysql版本是5.7,利用fastapi和tortoise-orm接口的方式返回查询到的响应结果。
下面创建了一个用于测试的数据表。包括主键id,varchar类型的name,json类型的code(数组)和info(映射)。
比方:code数据结构:["A1b2C3d4E5", "F6g7H8i9J0", "K1l2M3n4O5", "6q7R8s9T0", "U1v2W3x4Y5", "Z6a7B8c9D0", "E1F2g3H4i5", "J6k7L8m9N0", "O1P2q3R4s5", "T6U7v8W9x0", "Y1Z2a3B4c5", "D6E7F8g9H0", "I1j2K3l4M5", "N6O7P8q9R0", "S1T2U3v4W5", "X6Y7Z8a9B0"]
info数据结构:{"age": 30, "city": "New York", "name": "Alice", "contact": {"email": "alice@example.com", "phone": "123-456-7890"}, "education": "Bachelor"}

 1、查询info中age=30的数据
  1. @router.get('/jsontest/{keyword}/{value}', description="获取mysql的json值测试")
  2. async def search_(keyword: str, value: str):
  3.     query = f"SELECT * FROM jsontest WHERE JSON_CONTAINS(info->'$.{keyword}','{value}')"
  4.     conn = tortoise.Tortoise.get_connection("default")
  5.     try:
  6.         _, index_result = await conn.execute_query(query)
  7.     except Exception as ex:
  8.         error_msg = f"error:{ex.__class__.__name__}-{str(ex)}"
  9.         log_it(error_msg, level=logging.ERROR)
  10.         return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=error_msg)
  11.     finally:
  12.         await conn.close()
  13.     return JSONResponse(
  14.         status_code=status.HTTP_200_OK,
  15.         content=index_result
  16.     )
复制代码
  1. SELECT * FROM jsontest WHERE JSON_CONTAINS(info->'$.age','30')
复制代码
查询结果

 为了避免重复代码冗余,后续的查询直接写sql语句了。可以通过更改api接口传参,构造query语句达到一样的结果。
2、查询code数组中包罗"ANOPQRSTU8"的数据
  1. SELECT * FROM jsontest WHERE JSON_CONTAINS(code,'"ANOPQRSTU8"')
复制代码
3、查询info中city是New York并且code中包罗AWXYZ01239的数据
  1. SELECT * FROM jsontest WHERE JSON_CONTAINS(info->'$.city','"New York"') AND JSON_CONTAINS(code,'"AWXYZ01239"')
复制代码
4、查询info中包罗city和age的数据,指定的是"one"体现只需包罗任何一个路径即可,"all"体现必要包罗所有指定路径
  1. SELECT * FROM jsontest WHERE JSON_CONTAINS_PATH(info, 'one', '$.city', '$.age');
  2. SELECT * FROM jsontest WHERE JSON_CONTAINS_PATH(info, 'all', '$.city', '$.contact.email');
复制代码
5、查询Alice info数据中的city,age,以及contact里面的email。下面两种结果是一样的,只不过利用JSON_EXTRACT返回的是一个字段,而->这种方法返回的是拆分开的字段
  1. SELECT JSON_EXTRACT(info, '$.city','$.age','$.contact.email') AS name FROM jsontest WHERE name = 'Alice';
  2. SELECT info->'$.city',info->'$.age',info->'$.contact.email' FROM jsontest WHERE name = 'Alice'
复制代码
6、查询Alice code数组中前三个数据。数组类型的json只能通过索引获取值,假如想获取全部则改成'$
  • '即可。下面两种结果是一样的,只不过利用JSON_EXTRACT返回的是一个字段,而->这种方法返回的是拆分开的字段
    1. SELECT JSON_EXTRACT(code, '$[0]','$[1]','$[2]') AS res FROM jsontest WHERE name = 'Alice';
    2. SELECT code->'$[0]',code->'$[1]',code->'$[2]' FROM jsontest WHERE name = 'Alice';
    3. # 获取数组里面的所有数据
    4. SELECT JSON_EXTRACT(code, '$[*]') AS res FROM jsontest WHERE name = 'Alice';
    5. SELECT code->'$[*]'  FROM jsontest WHERE name = 'Alice';
    复制代码
    7、利用JSON_UNQUOTE去除 JSON 字符串的引号。上面返回的数据带有原始json的引号,这一点有时对结果处理特殊不友爱,可以利用JSON_UNQUOTE举行处理
    1. SELECT JSON_UNQUOTE(JSON_EXTRACT(info, '$.contact.email')) AS email FROM jsontest WHERE name = 'Alice';
    复制代码
    8、提取info映射里面的所有key,也可以查询嵌套字典里面的所有key
    1. SELECT JSON_KEYS(info) AS k FROM jsontest WHERE name = 'Alice';
    2. #查询嵌套字典的key
    3. SELECT JSON_KEYS(info->'$.contact') AS k FROM jsontest WHERE name = 'Alice';
    复制代码
    9、获取code数组和字典info的长度
    1. SELECT JSON_LENGTH(code, '$') as count  FROM jsontest WHERE name = 'Alice'
    2. SELECT JSON_LENGTH(info, '$') as count  FROM jsontest WHERE name = 'Alice'
    3. # 获取嵌套字典的长度
    4. SELECT JSON_LENGTH(info->'$.contact') as count  FROM jsontest WHERE name = 'Alice'
    复制代码
    10、搜刮数组和字典里面的值
    1. # 搜索字典中的value,one_or_all: 指定搜索所有匹配项还是仅找到的第一个匹配项
    2. SELECT JSON_SEARCH(info, 'all', "New York") AS search_result FROM jsontest
    3. # 搜索数组中的值,%A%模糊搜索含有A的数据
    4. SELECT JSON_SEARCH(code, 'all', '%A%') AS search_result FROM jsontest
    复制代码
     

    免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
  • 本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x
    回复

    使用道具 举报

    0 个回复

    倒序浏览

    快速回复

    您需要登录后才可以回帖 登录 or 立即注册

    本版积分规则

    滴水恩情

    金牌会员
    这个人很懒什么都没写!

    标签云

    快速回复 返回顶部 返回列表