biothings.api icon indicating copy to clipboard operation
biothings.api copied to clipboard

Problem with jmespath: unexpected behavior with single items (not arrays)

Open colleenXu opened this issue 2 years ago • 3 comments

I'm trying to query MyChem's drugcentral info and only keep drugcentral.bioactivity objects with the matching action_type value (POSITIVE MODULATOR). So I'm setting the parameter jmespath to drugcentral.bioactivity|[?action_type=='POSITIVE MODULATOR']

But if I try using that jmespath on this document C0017845_doesnt_work.json, I end up with drugcentral.bioactivity: null which is unexpected. (To retrieve this document yourself, use this GET query))

POST-query with chemical C0017845 that returns null

curl --location --globoff 'https://mychem.info/v1/query?size=1000&fields=drugcentral.bioactivity.uniprot.uniprot_id,drugcentral.bioactivity.action_type,drugcentral.bioactivity.act_source,drugcentral.bioactivity.organism&jmespath=drugcentral.bioactivity|[?action_type=='POSITIVE%20MODULATOR']' \
--header 'Content-Type: application/json' \
--data '{
  "q": [
      [ "C0017845", "POSITIVE MODULATOR"]
      ],
  "scopes": ["drugcentral.xrefs.umlscui", "drugcentral.bioactivity.action_type"]
}'

VS when I try using jmespath on a different document C0018549_works.json, it works as-intended. (To retrieve this document yourself, use this GET query))

A POST query with chemical C0018549 that works as-intended

curl --location --globoff 'https://mychem.info/v1/query?size=1000&fields=drugcentral.bioactivity.uniprot.uniprot_id,drugcentral.bioactivity.action_type,drugcentral.bioactivity.act_source,drugcentral.bioactivity.organism&jmespath=drugcentral.bioactivity|[?action_type=='POSITIVE MODULATOR']' \
--header 'Content-Type: application/json' \
--data '{
  "q": [
      [ "C0018549", "POSITIVE MODULATOR"]
      ],
  "scopes": ["drugcentral.xrefs.umlscui", "drugcentral.bioactivity.action_type"]
}'

I do notice a different between these two documents that may account for this:

  • in the first case, drugcentral.bioactivity is an object (since there was only 1 thing)
  • in the second case, drugcentral.bioactivity is an array of objects

If this is the key, I'd like jmespath to be able to gracefully handle both situations...

colleenXu avatar Apr 02 '24 00:04 colleenXu

Another example is described in https://github.com/biothings/biothings_explorer/issues/316#issuecomment-2030832144

colleenXu avatar Apr 02 '24 00:04 colleenXu

I've updated the opening post to match the discussions in Slack/add the json documents.

The proposed fix is to adjust the BioThings API's always_list parameter behavior (so it works before jmespath). Then adjust x-bte annotations to add it to queries using jmespath as a just-in-case. The syntax is always_list=drugcentral.bioactivity (aka path to the field that should be an array for jmespath to work on it).

colleenXu avatar Apr 09 '24 21:04 colleenXu

Assigning to myself to review and see if this is fixed.

colleenXu avatar Jul 30 '24 20:07 colleenXu