带有R中的列表/动态MySQL查询的JSON_SEARCH

时间:2019-05-06 07:32:38

标签: r json

我确实有一个名为user_activities的MySQL表,其中一列(activities)为JSON格式:

id      name    activities
1       Peter   ["football", "volley"]
2       Mary    ["football", "hockey", "basketball"]
3       Jason   ["volley", "hockey", "golf"]

我需要构造一个查询,给定一个活动列表,该查询将返回具有该列表中至少一个活动的所有那些用户。

示例1

提供列表

inputList <- list("football", "basketball")

MySQL查询应返回:

  id      name    activities
1       Peter   ["football", "volley"]
2       Mary    ["football", "hockey", "basketball"]

示例2

提供列表

inputList <- list("hockey", "golf", "basketball")

MySQL查询应返回:

id      name    activities
2       Mary    ["football", "hockey", "basketball"]
3       Jason   ["volley", "hockey", "golf"]

我知道可以按活动检查每个检查活动的元素的存在,例如:

 SELECT * FROM user_activities 
 WHERE JSON_SEARCH(`activities`, 'one', 'football') IS NOT NULL 
 OR JSON_SEARCH(`activities`, 'one', 'basketball') IS NOT NULL 
 OR JSON_SEARCH(`activities`, 'one', 'volley') IS NOT NULL 
 OR JSON_SEARCH(`activities`, 'one', 'hockey') IS NOT NULL 
 OR JSON_SEARCH(`activities`, 'one', 'golf') IS NOT NULL;

但是,如果某个活动不在指定列表(inputList)中,则我不想检查其在activities中的存在。每次我运行MySQL查询时,此inputList都会改变。

那么,有什么方法可以只检查列表中activities中的内容吗?我尝试过:

 SELECT * FROM user_activities
 WHERE JSON_SEARCH(`activities`, 'all', (",paste(shQuote(inputList, type = "sh"), collapse = ','),")) IS NOT NULL;

但是它“明显地”返回错误:

`Error in .local(conn, statement, ...): could not run statement: Operand should contain 1 column(s)`

因为JSON_SEARCH检查json数组或json文档中是否存在单个字符串,而我没有在函数中放入单个字符串。

还有JSON_CONTAINS

SELECT * FROM user_activities
WHERE JSON_CONTAINS(`activities`->'$[*]', JSON_ARRAY(", paste(shQuote(inputList, type = "sh"), collapse = ','), "))

返回inputList中的所有元素是否都在activities中,而我想知道activities中是否存在任何元素(不一定是全部)。

我该如何实现?

编辑

我发现了一个构建动态查询的解决方案(请参见下面的答案),这是针对PHP的问题MySQL Filter JSON_CONTAINS Any value from Array中所建议的。

1 个答案:

答案 0 :(得分:0)

我发现自己有了一个动态查询选项的解决方案,该选项在 Edit 部分中提到过。

library(tractor.base)

condition <- function(dbcolumn,inlist){
   cond <- implode(sapply(inlist, function(x) paste0("JSON_SEARCH(`",dbcolumn,"`, 'one', '", x,"') IS NOT NULL")), " OR ")
return(cond)
}

因此,如果我调用函数(问题中带有示例2):

condition("activities",inputList)

它返回:

"JSON_SEARCH(`activities`, 'one', 'hockey') IS NOT NULL OR JSON_SEARCH(`activities`, 'one', 'golf') IS NOT NULL OR JSON_SEARCH(`activities`, 'one', 'basketball') IS NOT NULL"

所以R中的MySQL查询最终看起来像这样:

query <- paste0("SELECT * FROM user_activities 
                 WHERE ", condition("activities", inputList),";")