【问题标题】:QueryDSL array overlap subquery functionQueryDSL数组重叠子查询功能
【发布时间】:2020-05-14 00:57:03
【问题描述】:

有一个包含 jsonb 列的表,其中包含 objectsarray,我设法设计了一个查询查找具有匹配至少一个参数的任何元素的行:

SELECT uuid, data FROM product p
WHERE arrayoverlap(array(SELECT jsonb_array_elements(data->'codes')->>'value'), array['57060279', '57627120']);

数据看起来像这样:

{"name": "Peppermint", "codes": [{"type": "EAN-8", "value": "57627120"}, {"type": "EAN-8", "value": "57060279"}], "number": "000000000000002136"]}
{"name": "AnotherNameForPeppermint", "codes": [{"type": "EAN-8", "value": "57060279"}], "number": "000000000000009571"}

有没有办法使用 QueryDSL 来运行这些? 到目前为止,我已经设法运行了一些基本函数,这些函数允许我匹配单个值,但对于数组我不知道如何。

import com.querydsl.core.types.Expression;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.ComparablePath;
import com.querydsl.core.types.dsl.EntityPathBase;
import com.querydsl.core.types.dsl.StringExpression;

import static com.querydsl.core.types.dsl.Expressions.booleanTemplate;
import static com.querydsl.core.types.dsl.Expressions.stringTemplate;

public class QuerydslUtil {
    public static BooleanExpression jsonbContains(StringExpression haystack, Expression<String> needle) {
        return booleanTemplate("FUNCTION('jsonb_contains', {0}, {1}) = true", haystack, needle);
    }

    public static StringExpression jsonbExtractPath(Object data, String propertyName) {
        return getStringExpression("jsonb_extract_path", data, propertyName);
    }

    public static StringExpression jsonbExtractPathText(Object data, String propertyName) {
        return getStringExpression("jsonb_extract_path_text", data, propertyName);
    }

    public static StringExpression getStringExpression(String function, Object data, String propertyName) {
        return stringTemplate("FUNCTION('" + function + "', {0}, {1})", data, propertyName);
    }
}

【问题讨论】:

    标签: arrays postgresql jpa querydsl


    【解决方案1】:

    找到了一个方法: 新的辅助方法:

    public class QuerydslUtil {
        public static BooleanExpression jsonbExistsAny(StringExpression arrayProperty, StringExpression array) {
            return booleanTemplate("FUNCTION('jsonb_exists_any', {0}, {1}) = true", arrayProperty, array);
        }
    
        public static BooleanExpression jsonbExistsAny(StringExpression arrayProperty, Collection<?> array) {
            String string = array.stream().map(Object::toString).collect(joining(","));
            return jsonbExistsAny(arrayProperty, stringToArray(string));
        }
    
        public static StringExpression stringToArray(String string) {
            return stringTemplate("FUNCTION('string_to_array', {0}, {1})", constant(string), constant(","));
        }
    }
    

    然后:

    StringExpression codesPath = jsonbExtractPath($.data, "codes");
    StringExpression codesValues = jsonbExtractPathText(codesPath, "value");
    // executor is a Spring Data QuerydslPredicateExecutor
    // codes is a Set<String>
    Iterable<Product> products = executor.findAll(jsonbExistsAny(codesValues , codes));
    

    【讨论】:

      猜你喜欢
      • 2013-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      • 2017-04-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多