2

I have a complex json object saved on a postgresql database and I want to find all entries that contain or begin with a substring inside an array. The json object:

    "configurations" : {
  "CVE_data_version" : "4.0",
  "nodes" : [ {
    "operator" : "OR",
    "cpe_match" : [ {
      "vulnerable" : true,
      "cpe23Uri" : "cpe:2.3:a:apache:http_server:*:*:*:*:*:*:*:*",
      "versionStartIncluding" : "2.4.0",
      "versionEndIncluding" : "2.4.41"
    } ]
  } ]
}

More specifically, I want to find all objects that begin with : "cpe:2.3:a:apache" in the "cpe23Uri" field.

Query I have made:

session.query(cvemodel.data['configurations']['nodes'][0]['cpe_match'].contains([{'cpe23Uri': 'cpe:2.3:a:apache:http_server:*:*:*:*:*:*:*:*'}])).all()

Problem with this query is that, it matches the whole word. If I put this:

session.query(cvemodel.data['configurations']['nodes'][0]['cpe_match'].contains([{'cpe23Uri': 'cpe:2.3:a:apache:http_server'}])).first()

It does not return anything!

1 Answer 1

1

If you are using PostgreSQL 12 or later, you can use jsonb_path_exists() and friends:

needle = 'cpe:2.3:a:apache:http_server'

session.query(cvemodel).\
    filter(func.jsonb_path_exists(
        cvemodel.data,
        '''$.configurations.nodes[0].cpe_match[*].cpe23Uri ?
           (@ starts with $needle)''',
        json.dumps({"needle": needle}))).\
    all()

If you want to check if cpe23Uri contains the needle, you can use the like_regex predicate, especially if you have a static "needle"; unfortunately like_regex only accepts string literals as right operand. Another option for a "contains" query would be to extract the cpe23Uri using either jsonb_path_query(), or accessors and jsonb_array_elements(), and use traditional LIKE, as described here.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.