0

我想更改查询以返回乘法值extra_fields,如何更改正则表达式?我也不明白什么extra_fields是 - 它是一个领域吗?如果是这样,为什么不使用表前缀调用它i.extra_fields

SELECT i.*,
    CASE WHEN i.modified = 0 THEN i.created ELSE i.modified END AS lastChanged,
    c.name AS categoryname,
    c.id AS categoryid,
    c.alias AS categoryalias,
    c.params AS categoryparams
FROM #__k2_items AS i
LEFT JOIN #__k2_categories AS c ON c.id = i.catid
WHERE i.published = 1
    AND i.access IN(1,1)
    AND i.trash = 0
    AND c.published = 1
    AND c.access IN(1,1)
    AND c.trash = 0
    AND (i.publish_up = '0000-00-00 00:00:00'
        OR i.publish_up <= '2013-06-12 22:45:19'
    )
    AND (i.publish_down = '0000-00-00 00:00:00'
        OR i.publish_down >= '2013-06-12 22:45:19'
    )
    AND extra_fields REGEXP BINARY '(.*{"id":"2","value":\["[^\"]*1[^\"]*","[^\"]*2[^\"]*","[^\"]*3[^\"]*"\]}.*)'
ORDER BY i.id DESC
4

3 回答 3

2

是表格的extra_fields一列#__k2_items。表限定符可以省略,因为它在此查询中没有歧义。该列是 JSON 编码的。这是一种序列化格式,用于存储设计上不可搜索的信息。应用正则表达式可能会在一天内起作用,但在另一天会失败,因为不能保证id前面的内容value(如您的示例中所示)。

正确的方式

过滤此问题的正确方法是忽略 SQL 查询中的extra_fields条件,而是在结果集中进行评估。例子:

$rows = $db->loadObjectList('id');
foreach ($rows as $id => $row) {
    $extra_fields = json_decode($row->extra_fields);
    if ($extra_fields->id != 2) {
         unset($rows[$id]);
    }
}

捷径

如果您无法更改数据库布局(对于您希望保持可更新的扩展来说确实如此),您必须将条件分成两个,因为无法保证子字段的特定顺序。由于某种原因,前一天value可能会发生。因此,将您的查询更改为 id

...
AND extra_fields LIKE '%"id":"2"%' 
AND extra_fields REGEXP BINARY '"value":\[("[^\"]*[123][^\"]*",?)+\]'
于 2013-06-13T02:05:45.900 回答
0

准备一个中间表来保存 extra_fields 的内容。每个 extra_fields 字段都会被转换成一系列记录。然后做一个连接。创建触发器和 cronjob 以保持临时表同步。

另一种方法是在 Perl 中编写 UDF 来解码该字段,但 AFAIK 它在 mysql 中不可索引。

使用外部搜索引擎超出了范围。

于 2013-06-14T08:37:24.690 回答
0

好的,我不想更改数据库结构,我得到了一些帮助并将正则表达式更改为AND extra_fields REGEXP BINARY '(.*{"id":"2","value":\[("[^\"]*[123][^\"]*",?)+\]}.*)' ,我得到了正确的结果谢谢

于 2013-06-14T08:58:00.903 回答