Search code examples
stormpathexpress-stormpath

Custom data search within an array


Is it possible to search an account's custom data to find a value contained in an array?

Something like:

?customData.[arrayName].{key}=value

The Stormpath docs don't mention array searching.


Solution

  • Searching for custom data in an array can definitely be done. The syntax is: customData.{fieldName}\[{index}\]=value where {index} can be the specific index you are looking for, or * if you want to find it anywhere in the array. (Note that the [] characters are escaped with a backslash or the query interpreter gets it confused with a range query.)

    If you leave off the index entirely, then \[*\] is implied. More precisely, Stormpath will check for either the value in the fieldName or the value as an element in an array of fieldName. However, syntactic sugar can only work if the array field is the last element in your search. Since you can put literally any JSON object into your custom data, Stormpath cannot check every single possibility. Imagine something like customData.foo.bar.baz.qux=bingo. Stormpath would not try to guess that maybe foo is an array, maybe bar is an array or not, maybe baz is an array or not - only maybe qux is an array or not. So, if you want to search an array of objects, you cannot leave out the \[*\].

    Here is an example. I have an account with the custom data:

    {
      "favoriteThings": [
        {
          "thing": "raindrops",
          "location": "on roses"
        },
        {
          "thing": "whiskers",
          "location": "on kittens"
        },
        {
          "thing": "snowflakes",
          "location": "on my nose and eye lashes"
        }
      ],
      "favoriteColors": [
        "blue",
        "grey"
      ]
    }
    

    The following queries will yield the following results:

    • customData.favoriteColors=blue will include this account.
    • customData.favoriteColors\[1\]=blue will not include this account because blue is not at index 1.
    • customData.favoriteThings\[*\].thing=whiskers will include this account
    • customData.favoriteThings\[*\].thing=ponies will not include this account because it does not list ponies as one of his favorite things, but may include other accounts with custom data in the same structure.
    • customData.favoriteThings.thing=whiskers would not include this account or any other accounts with the same custom data structure because in that case, Stormpath would be looking for a single nested JSON favoriteThings object, not an array.