1

I have this json object

{
  "index": {
    "queryString": "",
    "filtersMap": {},
    "selectedFilters": [],
    "queries": [
      {
        "filtered": {
          "filter": {
            "bool": {
              "must": [
                {
                  "term": {
                    "listingRecordState.id": "3"
                  }
                },
                {
                  "geo_distance": {
                    "distance": "100mi",
                    "property.location": {
                      "lat": "40.7608",
                      "lon": "-111.8910"
                    }
                  }
                }
              ]
            }
          }
        }
      }
    ],
    "filters": [],
    "_source": null,
    "size": 9
  },
  "query": {
    "query": {
      "filtered": {
        "filter": {
          "bool": {
            "must": [
              {
                "term": {
                  "listingRecordState.id": "3"
                }
              },
              {
                "geo_distance": {
                  "distance": "100mi",
                  "property.location": {
                    "lat": "40.7608",
                    "lon": "-111.8910"
                  }
                }
              }
            ]
          }
        }
      }
    },
    "size": 9
  }
}

I need to be able to update the lat and long inside this object without knowing the exact path, because the index inside each array could potentially change.

There will only be one key of "lat" and one key of "long" so duplicate key names will not be a problem.

I have tried several solutions using loops and recursion but have not been able to create or find something that works.

Thanks!

Ben Ahlander
  • 1,113
  • 11
  • 12
  • 1
    In your example `json` object, you do have two sets of `lat` and `lon` keys... – Blundering Philosopher Feb 14 '18 at 22:14
  • Possible duplicate of [Access / process (nested) objects, arrays or JSON](https://stackoverflow.com/questions/11922383/access-process-nested-objects-arrays-or-json) – Heretic Monkey Feb 14 '18 at 23:10
  • Please show us your "several solutions" so we know what you've tried and can tell you where you may have gone wrong. Otherwise, it really looks like you haven't tried anything and just want us to write code for you... – Heretic Monkey Feb 14 '18 at 23:11

1 Answers1

1

Here is a way to do that, but in this case all instances of the specified key will be updated - so be careful as the previous comment is correct that you have 'lon' and 'lat' twice in the data you posted.

var data =  {
      "index": {
        "queryString": "",
        "filtersMap": {},
        "selectedFilters": [],
        "queries": [
          {
            "filtered": {
              "filter": {
                "bool": {
                  "must": [
                    {
                      "term": {
                        "listingRecordState.id": "3"
                      }
                    },
                    {
                      "geo_distance": {
                        "distance": "100mi",
                        "property.location": {
                          "lat": "40.7608",
                          "lon": "-444.444"
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        ],
        "filters": [],
        "_source": null,
        "size": 9
      },
      "query": {
        "query": {
          "filtered": {
            "filter": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "listingRecordState.id": "3"
                    }
                  },
                  {
                    "geo_distance": {
                      "distance": "100mi",
                      "property.location": {
                        "lat": "40.7608",
                        "lon": "-111.8910"
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "size": 9
      }
    }
    
function updateByKey(obj, key, replace) {

  var j, key = key || '',
    obj = obj || {},
    keys = key.split("."),
    sObj = [],
    ssObj = [],
    isSelector = !!(keys.length > 0);

  var findKey = function(obj, key) {
    var k;
    for (k in obj) {
      if (k === key) {
        sObj.push(obj[k]);
        
        if (replace) obj[k] = replace
        
      } else if (typeof obj[k] == 'object') {
        findKey(obj[k], key);
      }
    }
  };

  if (isSelector) {
    var nKey = keys.shift();
    findKey(obj, nKey);

    while (keys.length > 0) {
      nKey = keys.shift();

      if (sObj.length > 0) {
        ssObj = sObj.slice(0), sObj = [];
        for (j in ssObj) {
          findKey(ssObj[j], nKey);
        }
      }
    }
  } else {
    findKey(obj, key);
  }

  // return occurrences of key in array
  return (sObj.length === 1) ? sObj.pop() : sObj;
};

var keyToFind = 'lon';
var replace = 5555;

console.log(updateByKey(data,'lon',replace))
console.log(updateByKey(data,'lon'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
Stacey Reiman
  • 666
  • 4
  • 13