1

I'm trying to create a table using nested json in an elasticsearch response.

The json looks like this:

{
    "took": 18,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "hits": {
        "total": 94,
        "max_score": 0.0,
        "hits": [

        ]
    },
    "aggregations": {
        "byDateTime": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
                {
                    "key": 1232037318222,
                    "key_as_string": "2012/01/12 16:34:18.000",
                    "doc_count": 2,
                    "byRecordNum": {
                        "doc_count_error_upper_bound": 0,
                        "sum_other_doc_count": 0,
                        "buckets": [
                            {
                                "key": 4876,
                                "doc_count": 2,
                                "byhash": {
                                    "doc_count_error_upper_bound": 0,
                                    "sum_other_doc_count": 0,
                                    "buckets": [
                                        {
                                            "key": "632854032d8e042ec124dbfad12e214a",
                                            "doc_count": 2,
                                            "byContent": {
                                                "doc_count_error_upper_bound": 0,
                                                "sum_other_doc_count": 0,
                                                "buckets": [
                                                    {
                                                        "key": "useraction",
                                                        "doc_count": 2,
                                                        "tophits": {
                                                            "hits": {
                                                                "total": 2,
                                                                "max_score": 1.0,
                                                                "hits": [
                                                                    {
                                                                        "_index": "myIndex",
                                                                        "_type": "log",
                                                                        "_id": "AVMN9FCKyxgCcpqsf1n3",
                                                                        "_score": 1.0,
                                                                        "_source": {
                                                                            "Field1": "Value1",
                                                                            "Field2": "Value2",
                                                                            "Field3": "Value3"
                                                                    }

The values that I need to access for the table are contained in the hits.hits section at the end.

In the controller I assign:

$scope.selectedactionhits = response.aggregations.byDateTime.buckets;

And then I can access the elements that I need using the following:

div ng-repeat="item in selectedactionhits">
    <div ng-repeat="a in item.byRecordNum.buckets">
    <div ng-repeat="b in a.byhash.buckets">

      <div ng-repeat="c in b.byContent.buckets">
        <div ng-repeat="d in c.tophits.hits.hits">
          {{d._source.Field1}}
          {{d._source.Field2}}
          {{d._source.Field3}}

What I need to do is create a table using the values form these fields, however as they are nested inside ng-repeat the table formatting does not work.

I've considered doing something in the controller to sort out the json, however I'm not sure how to do that.

Does anyone know how I can get this to work?

Thanks!

5
  • Likely best to flatten this data in controller Commented Feb 24, 2016 at 14:01
  • I'd highly recommend you normalize your data. Figure out exactly what you need from the response and bind only that to the view. Commented Feb 24, 2016 at 14:01
  • I've been trying to flatten this data, however I'm not able to get that to work in the controller. Do you know how I could do that? Thanks! Commented Feb 24, 2016 at 14:04
  • Similar loops to what you already have in view...push desired items into a new array. Commented Feb 24, 2016 at 14:13
  • Thanks, would you do this entirely in the controller? I'm trying to do that and that and when I do a push into a new array, all I seem to be getting is the key and not the object. Also, how do I loop through each object in the array? Commented Feb 24, 2016 at 14:15

2 Answers 2

2

After some cleaning of the JSON I came to what i think is the most simple solution. Using JSON.stringify and passing a function to the second parameter that will save the hits in an array.

function retrievehits (key, v) {
  if (key === 'hits' && v) {
    var isArray = Array.isArray(v);
    if (!isArray) {
      hits.push(JSON.stringify(Object.assign({}, v, {hits: undefined})));
    }
    else if (isArray) {
      for (var i = 0; i < v.length; i++) {
        retrievehits('hits', v[i]);
      }
      return;
    }
  }
  return v;

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

Comments

0

Thank you for all the responses. I've found a solution that seems to be working.

In the controller I have:

var flat = [];
        angular.forEach($scope.selectedactionhits, function(item){

          //second level
          angular.forEach(item.byRecordNum.buckets, function(item2){

            //Third level
            angular.forEach(item2.byhash.buckets, function(item3){

              //Fourth level
              angular.forEach(item3.byContent.buckets, function(item4){

                //fith level
                angular.forEach(item4.tophits.hits.hits, function(item5){
                  flat.push(item5);
                })
              })
            })
          })
        })
$scope.flatarray = flat;

And I can now use:

ng-repeat item in flatarray

and then get each element as:

{{item._source.Field1}}

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.