如何使用sql或嵌套动态条件过滤java中列表中的数据列表

问题描述

如何使用java动态过滤数据,假设我们有数据(没有pojo映射的map/json数组列表)

[
  {
    "id": "1001","type": "Internal","status": "Closed"
  },{
    "id": "1002","type": "External",{
    "id": "1003","status": "Open"
  },{
    "id": "1004","status": "Open"
  }
]

现在我们需要将过滤后的数据输出id > 1001 and ( type: 'External' or status: 'Open" )

 [ 
  {
    "id": "1002","status": "Open"
  } 
]

对如何实现这一目标有任何建议吗?

解决方法

使用 JSON 路径,下面是我作为示例发布的几个 JSONPath 查询

P.S :- Ur "Id" 应该是 Integer 类型的操作 > 或 <

代码:-

public static void main(String[] args) {
    String jsonData = "[\r\n" + 
            "  {\r\n" + 
            "    \"id\": 1001,\r\n" + 
            "    \"type\": \"Internal\",\r\n" + 
            "    \"status\": \"Closed\"\r\n" + 
            "  },\r\n" + 
            "  {\r\n" + 
            "    \"id\": 1002,\r\n" + 
            "    \"type\": \"External\",\r\n" + 
            "  {\r\n" + 
            "    \"id\": 1003,\r\n" + 
            "    \"status\": \"Open\"\r\n" + 
            "  },\r\n" + 
            "  {\r\n" + 
            "    \"id\": 1004,\r\n" + 
            "    \"status\": \"Open\"\r\n" + 
            "  }\r\n" + 
            "]";
    
    String filterId = "$.[?(@.id > 1001)]"; //For Id > 1001
    String filterType =  "$.[?(@.type in ['External'])]"; //for External type
    String filterTypeAndId =  "$.[?((@.id > 1001) && (@.type in ['Internal']))]"; //for External type with Id > 1001
    String filterTypeAndId2 =  "$.[?((@.id > 1001) && (@.type in ['Internal','External']))]"; //for External type with Id > 1001
    DocumentContext documentContext = JsonPath.parse(jsonData);
    System.out.println(documentContext.read(filterId).toString());
    System.out.println(documentContext.read(filterType).toString());
    System.out.println(documentContext.read(filterTypeAndId).toString());
    System.out.println(documentContext.read(filterTypeAndId2).toString());
}

结果是:-

[{"id":1002,"type":"External","status":"Closed"},{"id":1003,"type":"Internal","status":"Open"},{"id":1004,"status":"Open"}]

[{"id":1002,"status":"Closed"}]

[{"id":1003,"status":"Open"}]
,

我们可以使用 javascript 功能来解决条件。我们可以使用 Java ScriptEngineManager 来运行 javascript 表达式: 表达式可以是 type = 'Internal' AND status ='Open'

    private String getResult(String expression) {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");
        try {
            return engine.eval(expression).toString();
        } catch (Exception e) {
        }
        return null;
    }

,

您可以通过以下方法实现此目的:-

  1. 将json转成字符串
  2. 构造 JSONArray >> JSONArray jsonArray = new JSONArray(converted_json_String)
  3. 从 JsonArray 中取出 jsonArrayObject 并构造一个列表
  4. 使用 Collections.sort 方法并将您的比较逻辑部署到 JSON 键上 并构建您的排序 json。
,

试试这个代码,我假设你有一个对象列表。

List<YourCLass> filteredList = list
                    .stream()
                    .filter(obj -> obj.getId() > 1001 && (obj.getStatus().equals("Open") || obj.getType().equals("External")))
                    .collect(Collectors.toList());

filteredList 包含您期望的对象列表,使用 Object mapper 可以将其获取为 json 格式。

String filteredObjJson = new ObjectMapper().writeValuesAsString(filteredList);

在 pom.xml 中添加此依赖项或下载 lib 并将其添加到您的库中

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
</dependency>