Parse.com finding partial string in an array

I am trying to find a Parse.com field that is an array for a partial string.

When the field is in String format, I can do the following:

    // Update the filtered array based on the search text and scope.
// Remove all objects from the filtered search array
[self.searchResults removeAllObjects];
// Filter the array using NSPredicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.busnumber contains[c] %@", searchText];
self.searchResults = [NSMutableArray arrayWithArray:[self.objects filteredArrayUsingPredicate:predicate]];

      

This works, however the new field I want to find is an array. It works when I change it to the following:

    PFQuery * query = [PFQuery queryWithClassName:@"Bus"];
[query whereKey:@"route" equalTo:[NSString stringWithFormat:@"%@", searchText]];

[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {

    NSLog(@"Objects: %@", objects);

    if (error)
      {
        NSLog(@"ERROR: %@", error.localizedDescription);
      }
    else
      {
        [self.searchResults removeAllObjects];
        [self.searchResults addObjectsFromArray:objects];
        [self.searchDisplayController.searchResultsTableView reloadData];
      }}];

      

However, I need the exact string for this.

I want to be able to search for parts of a string though, when I change it to:

    [query whereKey:@"route" containsString:[NSString stringWithFormat:@"%@", searchText]];

      

I get:

[Error]: $regex only works on string fields (Code: 102, Version: 1.7.4)

      

Any ideas? Thank:)

+3


source to share


1 answer


What you tried is rational, but string qualifiers in PFQuery only work on strings.

I've seen this thread a lot on SO: PFQuery only provides basic comparisons for simple attributes. To do anything else, you need to query the supernet and perform application-level computations to reduce the superset to the desired set. This is expensive for two reasons: speed / space at the application level, network transfer add-on.

The first expense is mitigated and the second expense is eliminated using a cloud-based feature to reduce the add-on layer at the application level. If you still need add-in records on the client, consider moving this request to the cloud.



Specifically for this question, here is what I think the cloud function will resemble:

// very handy to have underscore available
var _ = require('underscore');

// return Bus objects whose route array contains strings which contain
// the passed routeSubstring (request.params.routeSubstring)
Parse.Cloud.define("busWithRouteContaining", function(request, response) {
    // for now, don't deal with counts > 1k
    // there a simple adjustment (using step recursively) to get > 1k results
    var query = new Parse.Query("Bus");
    query.find().then(function(buses) {
        var matching = _.select(buses, function(bus) {
            var route = bus.get("route");
            var routeSubstring = request.params.routeSubstring;
            return _.contains(route, function(routeString) {
                return routeString.includes(routeSubstring);
            }); 
        });
        response.success(matching);
    }, function(error) {
        response.error(error);
    });
});

      

If you decide to shortcut on the client and need help with the code, I can change it. This is going to be a fairly straightforward jump to predicateWithBlock:

with a block that iterates over an array attribute and checks rangeOfString:

on each.

+2


source







All Articles