You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@couchdb.apache.org by John <jo...@gmail.com> on 2013/03/30 15:44:53 UTC

JSON arrays in CouchDB

How does CouchDB handle JSON arrays? I'm trying to create a filter for
selective replication and I've tried everything to try and iterate through
the contents of an json array to check the contents but nothing seems to
work. My code is:

function (doc, rec) {
if (doc.expiryDate == null && doc.countries.indexOf(rec.query.country) !=
-1) {
    return doc;
} else {
    var expiry = doc.expiryDate;
    if (expiry > rec.query.today
&& doc.countries.indexOf(rec.query.country) != -1) {
        return doc;
    }
}}

And the JSON looks like:


"countries": [
   "GB",
   "US"],

I've ran out of ideas of how to get this working now, although I'm sure the
problem is "doc.countries"

Re: JSON arrays in CouchDB

Posted by John <jo...@gmail.com>.
ah sorry, I'm doing a pull replication from a CouchDB to TouchDB on
android. So the filter is running on CouchDB. Don't think it's possible to
do a  pull replication with the filter on TouchDB


On 30 March 2013 17:21, Robert Newson <rn...@apache.org> wrote:

> Oh, you said you were using CouchDB at the start of this.
>
> B.
>
> On 30 March 2013 17:12, John <jo...@gmail.com> wrote:
> > That makes sense, I thought (hoped) that the filter function just ignored
> > them.
> >
> > I'm using an android client (TouchDB) to do a filtered replication. Soon
> as
> > I have any mention of docs.countries in the filter function it fails to
> > replicate. I get an IOException error, which I assume is due to the fact
> > docs.countries is failing and causing nothing to get replicated. If I
> > filter on docs.expiryDate alone it works.
> >
> >
> > On 30 March 2013 16:59, Robert Newson <rn...@apache.org> wrote:
> >
> >> You'll need guard clauses for the presence of the countries field,
> >> design documents get replicated too :)
> >>
> >> You haven't specified what isn't working afaict. Can you clarify?
> >>
> >> B.
> >>
> >> On 30 March 2013 16:45, John <jo...@gmail.com> wrote:
> >> > Yes all docs (apart from the design docs) have the countries field,
> and
> >> it
> >> > always has atleast one entry. Would the fact expriyDate can sometimes
> be
> >> > set to null be an issue? Although the only working filter function
> I've
> >> > been able to create so far is with expiryDate.
> >> >
> >> > I tried your sample code and still can't get it to work, even with
> some
> >> > variations. I'm currently installing CouchDB on my desktop, as I'm
> >> assuming
> >> > then atleast I'll get access to the error logs, as iriscouch, which im
> >> > currently using doesn't provide them for free accounts
> >> >
> >> >
> >> > On 30 March 2013 15:27, Robert Newson <rn...@apache.org> wrote:
> >> >
> >> >> do *all* docs have a "countries" field? You'll be throw exceptions
> for
> >> >> docs that don't. Also, a filter function is expecting true/false
> >> >> responses. Something more like;
> >> >>
> >> >> function(doc, req) {
> >> >>   if (!doc.expiryDate) return false;
> >> >>   if (!doc.countries) return false;
> >> >>   if (!req.query.today) return false;
> >> >>   if (!req.query.country) return false;
> >> >>
> >> >>   return doc.expiryDate > req.query.today &&
> >> >> doc.countries.indexOf(req.query.country) !== -1;
> >> >> }
> >> >>
> >> >> On 30 March 2013 14:44, John <jo...@gmail.com> wrote:
> >> >> > How does CouchDB handle JSON arrays? I'm trying to create a filter
> for
> >> >> > selective replication and I've tried everything to try and iterate
> >> >> through
> >> >> > the contents of an json array to check the contents but nothing
> seems
> >> to
> >> >> > work. My code is:
> >> >> >
> >> >> > function (doc, rec) {
> >> >> > if (doc.expiryDate == null &&
> >> doc.countries.indexOf(rec.query.country) !=
> >> >> > -1) {
> >> >> >     return doc;
> >> >> > } else {
> >> >> >     var expiry = doc.expiryDate;
> >> >> >     if (expiry > rec.query.today
> >> >> > && doc.countries.indexOf(rec.query.country) != -1) {
> >> >> >         return doc;
> >> >> >     }
> >> >> > }}
> >> >> >
> >> >> > And the JSON looks like:
> >> >> >
> >> >> >
> >> >> > "countries": [
> >> >> >    "GB",
> >> >> >    "US"],
> >> >> >
> >> >> > I've ran out of ideas of how to get this working now, although I'm
> >> sure
> >> >> the
> >> >> > problem is "doc.countries"
> >> >>
> >>
>

Re: JSON arrays in CouchDB

Posted by Robert Newson <rn...@apache.org>.
Oh, you said you were using CouchDB at the start of this.

B.

On 30 March 2013 17:12, John <jo...@gmail.com> wrote:
> That makes sense, I thought (hoped) that the filter function just ignored
> them.
>
> I'm using an android client (TouchDB) to do a filtered replication. Soon as
> I have any mention of docs.countries in the filter function it fails to
> replicate. I get an IOException error, which I assume is due to the fact
> docs.countries is failing and causing nothing to get replicated. If I
> filter on docs.expiryDate alone it works.
>
>
> On 30 March 2013 16:59, Robert Newson <rn...@apache.org> wrote:
>
>> You'll need guard clauses for the presence of the countries field,
>> design documents get replicated too :)
>>
>> You haven't specified what isn't working afaict. Can you clarify?
>>
>> B.
>>
>> On 30 March 2013 16:45, John <jo...@gmail.com> wrote:
>> > Yes all docs (apart from the design docs) have the countries field, and
>> it
>> > always has atleast one entry. Would the fact expriyDate can sometimes be
>> > set to null be an issue? Although the only working filter function I've
>> > been able to create so far is with expiryDate.
>> >
>> > I tried your sample code and still can't get it to work, even with some
>> > variations. I'm currently installing CouchDB on my desktop, as I'm
>> assuming
>> > then atleast I'll get access to the error logs, as iriscouch, which im
>> > currently using doesn't provide them for free accounts
>> >
>> >
>> > On 30 March 2013 15:27, Robert Newson <rn...@apache.org> wrote:
>> >
>> >> do *all* docs have a "countries" field? You'll be throw exceptions for
>> >> docs that don't. Also, a filter function is expecting true/false
>> >> responses. Something more like;
>> >>
>> >> function(doc, req) {
>> >>   if (!doc.expiryDate) return false;
>> >>   if (!doc.countries) return false;
>> >>   if (!req.query.today) return false;
>> >>   if (!req.query.country) return false;
>> >>
>> >>   return doc.expiryDate > req.query.today &&
>> >> doc.countries.indexOf(req.query.country) !== -1;
>> >> }
>> >>
>> >> On 30 March 2013 14:44, John <jo...@gmail.com> wrote:
>> >> > How does CouchDB handle JSON arrays? I'm trying to create a filter for
>> >> > selective replication and I've tried everything to try and iterate
>> >> through
>> >> > the contents of an json array to check the contents but nothing seems
>> to
>> >> > work. My code is:
>> >> >
>> >> > function (doc, rec) {
>> >> > if (doc.expiryDate == null &&
>> doc.countries.indexOf(rec.query.country) !=
>> >> > -1) {
>> >> >     return doc;
>> >> > } else {
>> >> >     var expiry = doc.expiryDate;
>> >> >     if (expiry > rec.query.today
>> >> > && doc.countries.indexOf(rec.query.country) != -1) {
>> >> >         return doc;
>> >> >     }
>> >> > }}
>> >> >
>> >> > And the JSON looks like:
>> >> >
>> >> >
>> >> > "countries": [
>> >> >    "GB",
>> >> >    "US"],
>> >> >
>> >> > I've ran out of ideas of how to get this working now, although I'm
>> sure
>> >> the
>> >> > problem is "doc.countries"
>> >>
>>

Re: JSON arrays in CouchDB

Posted by John <jo...@gmail.com>.
On 30 March 2013 18:30, Jens Alfke <je...@couchbase.com> wrote:

>
>
> How are you using the filter function? If you’re specifying a filter in a
> pull replication, the filter function lives in (and runs on) the remote
> server. If it’s in a push replication, the function runs locally.
>

It's definitely a pull replication


> It really helps to say explicitly right up front what software and version
> you’re using, on the client as well as the server side. In particular, the
> Android version of TouchDB is rather unfinished, sort of in a pre-alpha
> state of development. (FYI, I’m the author of the iOS/Mac version of
> TouchDB, from which the Android version is ported.)
>
>
Yeah sorry about that, I assumed as the filter is running on the remote
CouchDB that it must be a problem with my filter implementation, which it
probably still is, and that TouchDB probably isn't the fault.


> > Soon as
> > I have any mention of docs.countries in the filter function it fails to
> > replicate. I get an IOException error, which I assume is due to the fact
> > docs.countries is failing and causing nothing to get replicated. If I
> > filter on docs.expiryDate alone it works.
>
> If this is a push replication, the problem might be that query parameters
> aren’t supported on Android, that is, rec.query might be undefined. IIRC,
> the initial implementation of filters didn’t support parameters, and that
> might not have been added to the Android version yet. So try replacing your
> use of rec.query with a hardcoded string like “GB” and see if that works.


Have previously hardcoding rec.query, removed any references to
doc.countries and  it works. It even works without hard coding and taking
the arguments from rec


>
If this is a pull replication, TouchDB/Android might not be passing the
> “?filter=“ parameter to the remote server’s _changes feed. Again, it’s
> possible this wasn’t originally supported. But I don’t know much about the
> exact development state of TouchDB/Android.
>
>
I've succesfully got the filter working without doc.countries.  That's why
I assumed it's an issue with my javascript on CouchDB rather than TouchDB

It’d be best to discuss this further either on the mobile-couchbase Google
> group, or by filing a Github issue against TouchDB-Android.
>
> —Jens


Ok thanks unless spots a problem with my filter and post on the
mobile-couchbase group

Re: JSON arrays in CouchDB

Posted by Jens Alfke <je...@couchbase.com>.
On Mar 30, 2013, at 10:12 AM, John <jo...@gmail.com> wrote:

> I'm using an android client (TouchDB) to do a filtered replication.

How are you using the filter function? If you’re specifying a filter in a pull replication, the filter function lives in (and runs on) the remote server. If it’s in a push replication, the function runs locally.

It really helps to say explicitly right up front what software and version you’re using, on the client as well as the server side. In particular, the Android version of TouchDB is rather unfinished, sort of in a pre-alpha state of development. (FYI, I’m the author of the iOS/Mac version of TouchDB, from which the Android version is ported.)

> Soon as
> I have any mention of docs.countries in the filter function it fails to
> replicate. I get an IOException error, which I assume is due to the fact
> docs.countries is failing and causing nothing to get replicated. If I
> filter on docs.expiryDate alone it works.

If this is a push replication, the problem might be that query parameters aren’t supported on Android, that is, rec.query might be undefined. IIRC, the initial implementation of filters didn’t support parameters, and that might not have been added to the Android version yet. So try replacing your use of rec.query with a hardcoded string like “GB” and see if that works.

If this is a pull replication, TouchDB/Android might not be passing the “?filter=“ parameter to the remote server’s _changes feed. Again, it’s possible this wasn’t originally supported. But I don’t know much about the exact development state of TouchDB/Android.

It’d be best to discuss this further either on the mobile-couchbase Google group, or by filing a Github issue against TouchDB-Android.

—Jens

Re: JSON arrays in CouchDB

Posted by John <jo...@gmail.com>.
That makes sense, I thought (hoped) that the filter function just ignored
them.

I'm using an android client (TouchDB) to do a filtered replication. Soon as
I have any mention of docs.countries in the filter function it fails to
replicate. I get an IOException error, which I assume is due to the fact
docs.countries is failing and causing nothing to get replicated. If I
filter on docs.expiryDate alone it works.


On 30 March 2013 16:59, Robert Newson <rn...@apache.org> wrote:

> You'll need guard clauses for the presence of the countries field,
> design documents get replicated too :)
>
> You haven't specified what isn't working afaict. Can you clarify?
>
> B.
>
> On 30 March 2013 16:45, John <jo...@gmail.com> wrote:
> > Yes all docs (apart from the design docs) have the countries field, and
> it
> > always has atleast one entry. Would the fact expriyDate can sometimes be
> > set to null be an issue? Although the only working filter function I've
> > been able to create so far is with expiryDate.
> >
> > I tried your sample code and still can't get it to work, even with some
> > variations. I'm currently installing CouchDB on my desktop, as I'm
> assuming
> > then atleast I'll get access to the error logs, as iriscouch, which im
> > currently using doesn't provide them for free accounts
> >
> >
> > On 30 March 2013 15:27, Robert Newson <rn...@apache.org> wrote:
> >
> >> do *all* docs have a "countries" field? You'll be throw exceptions for
> >> docs that don't. Also, a filter function is expecting true/false
> >> responses. Something more like;
> >>
> >> function(doc, req) {
> >>   if (!doc.expiryDate) return false;
> >>   if (!doc.countries) return false;
> >>   if (!req.query.today) return false;
> >>   if (!req.query.country) return false;
> >>
> >>   return doc.expiryDate > req.query.today &&
> >> doc.countries.indexOf(req.query.country) !== -1;
> >> }
> >>
> >> On 30 March 2013 14:44, John <jo...@gmail.com> wrote:
> >> > How does CouchDB handle JSON arrays? I'm trying to create a filter for
> >> > selective replication and I've tried everything to try and iterate
> >> through
> >> > the contents of an json array to check the contents but nothing seems
> to
> >> > work. My code is:
> >> >
> >> > function (doc, rec) {
> >> > if (doc.expiryDate == null &&
> doc.countries.indexOf(rec.query.country) !=
> >> > -1) {
> >> >     return doc;
> >> > } else {
> >> >     var expiry = doc.expiryDate;
> >> >     if (expiry > rec.query.today
> >> > && doc.countries.indexOf(rec.query.country) != -1) {
> >> >         return doc;
> >> >     }
> >> > }}
> >> >
> >> > And the JSON looks like:
> >> >
> >> >
> >> > "countries": [
> >> >    "GB",
> >> >    "US"],
> >> >
> >> > I've ran out of ideas of how to get this working now, although I'm
> sure
> >> the
> >> > problem is "doc.countries"
> >>
>

Re: JSON arrays in CouchDB

Posted by Robert Newson <rn...@apache.org>.
You'll need guard clauses for the presence of the countries field,
design documents get replicated too :)

You haven't specified what isn't working afaict. Can you clarify?

B.

On 30 March 2013 16:45, John <jo...@gmail.com> wrote:
> Yes all docs (apart from the design docs) have the countries field, and it
> always has atleast one entry. Would the fact expriyDate can sometimes be
> set to null be an issue? Although the only working filter function I've
> been able to create so far is with expiryDate.
>
> I tried your sample code and still can't get it to work, even with some
> variations. I'm currently installing CouchDB on my desktop, as I'm assuming
> then atleast I'll get access to the error logs, as iriscouch, which im
> currently using doesn't provide them for free accounts
>
>
> On 30 March 2013 15:27, Robert Newson <rn...@apache.org> wrote:
>
>> do *all* docs have a "countries" field? You'll be throw exceptions for
>> docs that don't. Also, a filter function is expecting true/false
>> responses. Something more like;
>>
>> function(doc, req) {
>>   if (!doc.expiryDate) return false;
>>   if (!doc.countries) return false;
>>   if (!req.query.today) return false;
>>   if (!req.query.country) return false;
>>
>>   return doc.expiryDate > req.query.today &&
>> doc.countries.indexOf(req.query.country) !== -1;
>> }
>>
>> On 30 March 2013 14:44, John <jo...@gmail.com> wrote:
>> > How does CouchDB handle JSON arrays? I'm trying to create a filter for
>> > selective replication and I've tried everything to try and iterate
>> through
>> > the contents of an json array to check the contents but nothing seems to
>> > work. My code is:
>> >
>> > function (doc, rec) {
>> > if (doc.expiryDate == null && doc.countries.indexOf(rec.query.country) !=
>> > -1) {
>> >     return doc;
>> > } else {
>> >     var expiry = doc.expiryDate;
>> >     if (expiry > rec.query.today
>> > && doc.countries.indexOf(rec.query.country) != -1) {
>> >         return doc;
>> >     }
>> > }}
>> >
>> > And the JSON looks like:
>> >
>> >
>> > "countries": [
>> >    "GB",
>> >    "US"],
>> >
>> > I've ran out of ideas of how to get this working now, although I'm sure
>> the
>> > problem is "doc.countries"
>>

Re: JSON arrays in CouchDB

Posted by John <jo...@gmail.com>.
Yes all docs (apart from the design docs) have the countries field, and it
always has atleast one entry. Would the fact expriyDate can sometimes be
set to null be an issue? Although the only working filter function I've
been able to create so far is with expiryDate.

I tried your sample code and still can't get it to work, even with some
variations. I'm currently installing CouchDB on my desktop, as I'm assuming
then atleast I'll get access to the error logs, as iriscouch, which im
currently using doesn't provide them for free accounts


On 30 March 2013 15:27, Robert Newson <rn...@apache.org> wrote:

> do *all* docs have a "countries" field? You'll be throw exceptions for
> docs that don't. Also, a filter function is expecting true/false
> responses. Something more like;
>
> function(doc, req) {
>   if (!doc.expiryDate) return false;
>   if (!doc.countries) return false;
>   if (!req.query.today) return false;
>   if (!req.query.country) return false;
>
>   return doc.expiryDate > req.query.today &&
> doc.countries.indexOf(req.query.country) !== -1;
> }
>
> On 30 March 2013 14:44, John <jo...@gmail.com> wrote:
> > How does CouchDB handle JSON arrays? I'm trying to create a filter for
> > selective replication and I've tried everything to try and iterate
> through
> > the contents of an json array to check the contents but nothing seems to
> > work. My code is:
> >
> > function (doc, rec) {
> > if (doc.expiryDate == null && doc.countries.indexOf(rec.query.country) !=
> > -1) {
> >     return doc;
> > } else {
> >     var expiry = doc.expiryDate;
> >     if (expiry > rec.query.today
> > && doc.countries.indexOf(rec.query.country) != -1) {
> >         return doc;
> >     }
> > }}
> >
> > And the JSON looks like:
> >
> >
> > "countries": [
> >    "GB",
> >    "US"],
> >
> > I've ran out of ideas of how to get this working now, although I'm sure
> the
> > problem is "doc.countries"
>

Re: JSON arrays in CouchDB

Posted by Robert Newson <rn...@apache.org>.
do *all* docs have a "countries" field? You'll be throw exceptions for
docs that don't. Also, a filter function is expecting true/false
responses. Something more like;

function(doc, req) {
  if (!doc.expiryDate) return false;
  if (!doc.countries) return false;
  if (!req.query.today) return false;
  if (!req.query.country) return false;

  return doc.expiryDate > req.query.today &&
doc.countries.indexOf(req.query.country) !== -1;
}

On 30 March 2013 14:44, John <jo...@gmail.com> wrote:
> How does CouchDB handle JSON arrays? I'm trying to create a filter for
> selective replication and I've tried everything to try and iterate through
> the contents of an json array to check the contents but nothing seems to
> work. My code is:
>
> function (doc, rec) {
> if (doc.expiryDate == null && doc.countries.indexOf(rec.query.country) !=
> -1) {
>     return doc;
> } else {
>     var expiry = doc.expiryDate;
>     if (expiry > rec.query.today
> && doc.countries.indexOf(rec.query.country) != -1) {
>         return doc;
>     }
> }}
>
> And the JSON looks like:
>
>
> "countries": [
>    "GB",
>    "US"],
>
> I've ran out of ideas of how to get this working now, although I'm sure the
> problem is "doc.countries"