Search code examples
jsoncouchbaseaggregationsql++nosql-aggregation

N1QL aggregation Query Couchbase


I'm trying to write a query that will aggregate results for documents for given day of week for a combination of source and target.

Documents in the bucket look like this

{
  "source": "test-source-1",
  "target": "test-target-1",
  "2022-03-05": {
    "day_of_week": "Saturday",
    "result-1": 467.5326086956522,
    "result-2": {
      "low_limit": 21.0,
      "high_limit": 14.0
    },
    "result-3": {
      "low_limit": 3.0,
      "high_limit": 2.0
    }
  },
  "2022-03-06": {
    "day_of_week": "Sunday",
    "result-1": 467.5326086956522,
    "result-2": {
      "low_limit": 21.0,
      "high_limit": 14.0
    },
    "result-3": {
      "low_limit": 3.0,
      "high_limit": 2.0
    }
  },
  "2022-03-12": {
    "day_of_week": "Saturday",
    "result-1": 467.5326086956522,
    "result-2": {
      "low_limit": 21.0,
      "high_limit": 14.0
    },
    "result-3": {
      "low_limit": 1.0,
      "high_limit": 1.0
    },
    "result-4": {
      "low_limit": 3.0,
      "high_limit": 2.0
    }
  },
  "2022-03-13": {
    "day_of_week": "Sunday",
    "result-1": 190.8181818181818,
    "result-2": {
      "low_limit": 30.0,
      "high_limit": 30.0
    },
    "result-3": {
      "low_limit": 1.0,
      "high_limit": 1.0
    },
    "result-4": {
      "low_limit": 6.0,
      "high_limit": 6.0
    }
  }
}

{
  "source": "test-source-2",
  "target": "test-target-2",
  "2022-03-05": {
    "day_of_week": "Saturday",
    "result-1": 300,
    "result-2": {
      "low_limit": 21.0,
      "high_limit": 14.0
    },
    "result-3": {
      "low_limit": 3.0,
      "high_limit": 2.0
    }
  },
  "2022-03-06": {
    "day_of_week": "Sunday",
    "result-1": 400,
    "result-2": {
      "low_limit": 21.0,
      "high_limit": 14.0
    },
    "result-3": {
      "low_limit": 3.0,
      "high_limit": 2.0
    }
  },
  "2022-03-12": {
    "day_of_week": "Saturday",
    "result-1": 300,
    "result-2": {
      "low_limit": 21.0,
      "high_limit": 14.0
    },
    "result-3": {
      "low_limit": 1.0,
      "high_limit": 1.0
    },
    "result-4": {
      "low_limit": 3.0,
      "high_limit": 2.0
    }
  },
  "2022-03-13": {
    "day_of_week": "Sunday",
    "result-1": 400,
    "result-2": {
      "low_limit": 30.0,
      "high_limit": 30.0
    },
    "result-3": {
      "low_limit": 1.0,
      "high_limit": 1.0
    },
    "result-4": {
      "low_limit": 6.0,
      "high_limit": 6.0
    }
  }
}

And the expected result should be as follows if we are Querying for where day_of_week = Saturday in all documents:

[
    {
        "2022-03-05": {
            "day_of_week": "Saturday",
            "result-1": 467.5326086956522,
            "result-2": {
              "low_limit": 21.0,
              "high_limit": 14.0
            },
            "result-3": {
              "low_limit": 3.0,
              "high_limit": 2.0
            }
          },
        "2022-03-12": {
            "day_of_week": "Saturday",
            "result-1": 467.5326086956522,
            "result-2": {
              "low_limit": 21.0,
              "high_limit": 14.0
            },
            "result-3": {
              "low_limit": 1.0,
              "high_limit": 1.0
            },
            "result-4": {
              "low_limit": 3.0,
              "high_limit": 2.0
            }
          }
        "source": "test-source-1",
        "target": "test-target-1"
    },
    {
        "2022-03-05": {
            "day_of_week": "Saturday",
            "result-1": 300,
            "result-2": {
              "low_limit": 21.0,
              "high_limit": 14.0
            },
            "result-3": {
              "low_limit": 3.0,
              "high_limit": 2.0
            }
          },
        "2022-03-12": {
            "day_of_week": "Saturday",
            "result-1": 300,
            "result-2": {
              "low_limit": 21.0,
              "high_limit": 14.0
            },
            "result-3": {
              "low_limit": 1.0,
              "high_limit": 1.0
            },
            "result-4": {
              "low_limit": 3.0,
              "high_limit": 2.0
            }
          },
        "source": "test-source-2",
        "target": "test-target-2"
    }
]

I have the following query till now but it returns all the day_of_week. I know I am selecting b.* which will return for all days just unsure how to filter this out for each day i.e only Saturday or Sunday

SELECT b.*
FROM `history-dummy`.`_default`.`node-to-node` AS b
WHERE ANY v IN OBJECT_VALUES(b) SATISFIES v.`day_of_week`="Saturday" END;

Any help would be greatly appreciated. Thanks


Solution

  • SELECT RAW OBJECT n:v FOR n:v IN b WHEN v.day_of_week = "Saturday" END
    FROM `history-dummy`.`_default`.`node-to-node` AS b
    WHERE ANY v IN OBJECT_VALUES(b) SATISFIES v.`day_of_week`="Saturday" END;
    

    Add source, target

    SELECT b.source, b.target, OBJECT n:v FOR n:v IN b WHEN v.day_of_week = "Saturday" END.*
    FROM `history-dummy`.`_default`.`node-to-node` AS b
    WHERE ANY v IN OBJECT_VALUES(b) SATISFIES v.`day_of_week`="Saturday" END;
    
    CREATE INDEX `idx1` ON `history-dummy`.`_default `.`node-to-node`(DISTINCT ARRAY v.day_of_week FOR v IN OBJECT_VALUES(self) END);