0

I have 3000 objects each with a number of properties creating a 72,000 line 2MB JSON file.

The JSON is effectively a database of objects that need to be filtered by a text search filter and also by matching values against an array of values.

In the initial view I perform this in my service:

  this.loadJsonFile = function(url, process) {
    var defer = $q.defer();
    if (angular.isDefined(cache[url])) {
      if (angular.isDefined(cache[url]['then'])) {
        return cache[url];
      }
      defer.resolve(cache[url]);
      return defer.promise;
    }

    $http.get(url).success(function(data) {
      if (process) {
        data = process(data);
      }
      cache[url] = data;
      defer.resolve(data);
    }).error(function(err){
      defer.reject(err);
    });
    cache[url] = defer.promise;
    return defer.promise;
  };

  this.getExercises = function() {
    return this.loadJsonFile('data/exercises.json');
  };

and in my controller all results are exposed to $scope by:

api.getExcercises().then(function(data) {
  $scope.allExercises = data.results;
});

I limit results by :

$scope.limit = 56;

Previously I have stayed away from calling the server every time I need to search as the number of calls would be very high! This works ok on an iPad Air 2 and iPhone 6 where there is plenty of power, however on a Galaxy Tab it is pretty poor.

I need help on a strategy of only exposing a limited number of results to the $scope as I think the shear amount of data being filtered and churned around is causing my poor performance. I am fine with a search / filter function being run and breaking the seamless nature of the live search feature so long as when the results are exposed to $scope (following a loading screen say) the performance is really sharp.

Looking into the server situation I am not keen on hitting my Parse.com server as its not that Angular friendly, however the Async nature of Firebase might work. I have simply uploaded my JSON and attached the data to the $scope via :

var ref = new Firebase("https://URL_HERE.firebaseio.com/results"); 
$scope.allExercises = $firebaseArray(ref);

Which works pretty similarly to my local JSON method. However I wonder if it is possible to perform the following using Firebase?

  1. Load an initial 50 results ordered by Name.
  2. When typing in the text search a Query is performed and the $scope is delivered the results.
  3. When adding values to the filter array the data on Firebase is queried against the values and results exposed to the $scope.
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Taylorsuk
  • 1,419
  • 1
  • 16
  • 51
  • So I built and an ionic app and needed to use a 118MB JSON file with over 18000 entries. What I did is I put it all into a mongo DB and then queried it. It is super fast and works very well with a nodejs/express server or you can query the database directly from the app. I have not looked into firebase but if you are looking for a fast, direct, and javascript friendly database I would check out mongolab.com – Jess Patton May 29 '15 at 16:09
  • Jess many thanks for your comment. Can you expand a little on your server setup? I've not used nodejs/express before. – Taylorsuk May 29 '15 at 16:13
  • 1
    yeah, so I have a node server. Express is used to make routes. In the node server you connect to your database, the create a path like www.website.com/api/:param. The parameter is taken in and used to query the mongo database. I would take a loot at this to get started. Pretty much you make a restful api for your mongo DB http://thejackalofjavascript.com/nodejs-restify-mongolab-build-rest-api/ – Jess Patton May 29 '15 at 16:23
  • it is all javascript and JSON objects, you can also use mongo to run functions server side. So once the data is passed to the node server you can have a function sort it before sending it client side – Jess Patton May 29 '15 at 16:23
  • 1
    if you want to see how an app using this performs my app is Sidekick for elite dangerous on the play store. The queries are actually super fast for having such a huge database. As of now my server is hosted on heroku and my database on mongolab. – Jess Patton May 29 '15 at 16:24
  • Can you give me a station name? I don't know what i'm looking for on your app... – Taylorsuk May 29 '15 at 16:43
  • use the station name reilly hub – Jess Patton May 29 '15 at 17:56
  • Ok cool... there is a spelling mistake in the connection error, and is is possible to do a `LIKE` query so if I searched `reilly` should it work? – Taylorsuk May 29 '15 at 18:50
  • I dont have that set up in my app but you can http://stackoverflow.com/questions/3305561/how-to-query-mongodb-with-like. Also I am a terrible speller haha – Jess Patton May 29 '15 at 21:34

2 Answers2

2

Please take some time to go through the Firebase guide. It will prevent many questions, that are answered there already.

  1. Yup, something like:

    ref.orderByChild('name').limitToFirst(50);
    
  2. You'd have to run a query like:

    ref.orderByChild('name').startAt(searchString).limitToFirst(50);
    

    Note that Firebase querying does not support wildcard searches. See the guide's section on querying for more info.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Thanks Frank, however this only answers the initial part of my question - I have used this code and it works fine. So firebase is unable to query / filter on the server? that is all done client side? – Taylorsuk May 29 '15 at 16:15
  • My code shows how to do a "starts with" like query, which will be executed on the server (as long as you've defined an index on `name`). Wildcard and fuzzy searches are not currently a feature of Firebase's querying feature. – Frank van Puffelen May 30 '15 at 04:46
1

Your problem is that your number of watchers is enormous on your datas, and having automatic filters creates even more watchers that are called twice.

I suggest you to implement a database and a Search capability.

For a free solution (as FireBase is paid) I suggest you to use a sqlite database with the cordova sqlite plugin

This is working pretty well on android and ios and, with some work on Windows Phone too ;)

aorfevre
  • 5,034
  • 3
  • 21
  • 51
  • Each time there is a new update of my app I will be changing this database / expanding it. Also I have been considering remote options so that I can update the source data without having to update the app as Apple's review times are killing me!! – Taylorsuk May 29 '15 at 17:08
  • This is a solution but will increase number of queries from App to WebServices. I personnaly manage a Sync Service on my app. – aorfevre May 29 '15 at 17:10
  • with my mongoDB I have to totally remake it every 24 hours because that is when i get the new JSON file. So I have a batch script that drops the collection and remakes it from a JSON file. Super easy – Jess Patton May 29 '15 at 17:57