Home > front end >  Is it possible to search an entire JSON object regardless of how deep it is for a specific keyword w
Is it possible to search an entire JSON object regardless of how deep it is for a specific keyword w

Time:06-21

For any JSON object, for example,

{
  "Book1": {
    "Genres": [
      "horror",
      "thriller",
      "drama"
    ],
    "Description": "Extremely scary book.",
    "Author": "Jane Doe"
  },
  "Book2": {
    "Genres": [
      "Romance",
      "drama"
    ],
    "Description": "Very romantic book.",
    "Author": "John Doe"
  }
}

Is it possible to do a general search over every single key? For example, if you search for "horror" it would return

{
      "Book1": {
        "Genres": [
          "horror",
          "thriller",
          "drama"
        ],
        "Description": "Extremely scary book.",
        "Author": "Jane Doe"
      }
}

as the word is found in the "Genres" or if you search for "romantic" it would return Book2 as the word is contained in the description. I want to avoid having to specify the key in which the value is found in but rather have a general search over the entire object.

CodePudding user response:

Use .. to traverse the tree, strings to compare only strings, any to return true on first match, and map_values to retain the original tree structure.

jq 'map_values(select(any(..; strings == "horror")))'
{
  "Book1": {
    "Genres": [
      "horror",
      "thriller",
      "drama"
    ],
    "Description": "Extremely scary book.",
    "Author": "Jane Doe"
  }
}

Demo

To include substrings in the search, use contains instead:

jq 'map_values(select(any(.. | strings; contains("romantic"))))'
{
  "Book2": {
    "Genres": [
      "Romance",
      "drama"
    ],
    "Description": "Very romantic book.",
    "Author": "John Doe"
  }
}

Demo

You may also want to convert to upper or lower case using ascii_upcase or ascii_downcase to have a case-insensitive search, or use test for a regex search.

  • Related