2

Considering: doc profile { _id:"1", name:"john", likes: ["2222","1111"] }

doc likes { _id:"2222", value:"true" }

{ _id:"1111", value:"false" }

I have a filter on my xamarin app to get the profile, and it works well but I need to include the "children" (linked) docs... I can do this with a view setting include_docs=true but I want couchdb to filter so I can use replication. Also, it would be possible to accomplish the same result if I could use a reduce function to filter data, but I can't make the filter use the reduce function.. So, any idea?

the expected result would be:

doc profile { _id:"1", name:"john", likes: { {_id:"2222", value:"true"}, {_id:"1111", value:"false"] } }

Thanks!

VeYroN
  • 760
  • 9
  • 19

1 Answers1

1

I can do this with a view setting include_docs=true but I want couchdb to filter so I can use replication

You might already know this but you can use couchdb views as filters.

Also, it would be possible to accomplish the same result if I could use a reduce function to filter data

The reduce function is for "reducing" the values that are returned by the map function. The map function returns a key and a value like so:

emit(key,value)

The reduce function only gets the keys and the values that are returned from a map function. For example if you call a view with

?key=abc

and it returns results like

[{
_id:...,
type: abc
},
{
_id:...,
type:abc
}
....
]

You already have all the documents filtered by the key "abc". The reduce function will get as inputs the key, the value and a rereduce parameters. If you use the reduce function as a post map processing step to further filter the results from the view there will be two problems:

  1. There is no way to pass a parameter to a reduce. The keys that you specify will only be used by the map function and then passed as they are to reduce.

  2. It is not a good idea anyway. With reduce you want to return a small value that aggregates the results you get from a view. So taking the above example if you return say an integer as a value from the map function ( in emit(key,value)//suppose that the value is an integer) the reduce function may return a sum or aggregate of those values. But trying to return a modified document is not what reduce function is for. From the docs

"A reduce function must reduce the input values to a smaller output value. If you are building a composite return structure in your reduce, or only transforming the values field, rather than summarizing it, you might be misusing this feature. "

List functions might be more suited to what you are trying to do. If you want to process the results of the view query before returning them they are they way to go.

In list functions you get a set of results returned by the view function. You can even pass additional parameters if you'd like to apply complex filters on them. But you won't be able to use list functions for replication.

Finally replication works on a document level. Documents have _rev fields that is used by the replicator process to check what version the document is in before the replication is performed. So you won't be able to replicate the results returned by a view. Only the documents will be replicated.

Akshat Jiwan Sharma
  • 15,430
  • 13
  • 50
  • 60
  • 1
    Thanks for the very useful info! I wanted to use replication but if i can't use it for this what can I use? REST? Or is there another way to do it? – VeYroN Jun 04 '15 at 14:17
  • Glad you found it useful. Replication has a lot of uses. [The guide](http://guide.couchdb.org/draft/replication.html) gives a good overview of what it might be used for. – Akshat Jiwan Sharma Jun 04 '15 at 16:13
  • 1
    It definitely not recommended to use lists as filter in that use case. This will cause serious performance issues when the profile amount raises. Instead a view with a multipart key is a solid solution. The index can be based on the profile docs only. The view map function would emit several times for every doc - one row for the "parent" profile doc and also one row per likes-item. Finally a little trick makes it perfect - emit the property `_id` in the value of the likes-rows. Then this row will have the original likes-doc (instead of the profile-doc) attached when `include_docs=true` is used – Ingo Radatz Jun 05 '15 at 19:27
  • Yes. Good point about the performance of list functions as compared to the views. – Akshat Jiwan Sharma Jun 06 '15 at 06:50