Grouping documents without views


#1

Hello everyone,

In my documents I have a property called “level”. I have 3 views now, according to documents’ “type” properties: “mainForums”, “popularForums” and “newestForums”.

In the mainForums view, my map reduce function checks not only the type but also the “level” and takes docs only with level = 1.

Now, I have to do that for other docs with different “level” values but I don’t know if I should do it by creating more views or doing something else. I don’t think it would be efficient to create more views and check like below but I might be wrong:

if(doc.type == "mainForums" && doc.level == 1)

Any ideas? Thanks.


#2

may be you can using following view:

function(doc,meta){
emit([doc.type,doc.level],null);
}

then you can use
["mainForums",1] or ["mainForums",2] or ["popularForums",1] etc

as key to query doc’s id.


#3

@atom_yang Hi, thanks for the response. My map function is like following for view_default (stores mainForums) view:

function (doc, meta) {
  
  var key,value;
 	if(doc.type == "mainForums" && doc.level == 1){
   key = [doc.type,doc.id]
   value = {Id : doc.id, Title : doc.title, Description : doc.description, Parent: doc.parent, HasChild : doc.hasChild, Level : doc.level, ImageUrl : "http://icon.donanimhaber.com/mobile-forum-icons/" + doc.iconPath, AvarageColor: doc.avarageColor,  RepMode : doc.repMode, iconPath : doc.iconPath, MessageCountThisWeek : doc.messageCountThisWeek, TopicCountThisWeek : doc.topicCountThisWeek}
  emit(key, value);
  }
} 

I’m using type+id for the key. But when I get data I call the view not the docs. How the “key” is relevant? How am I gonna call only “level”=“2” docs while getting the data? This level thing is ony for mainForums by the way. Also I’m using MVC for the coding part. This is the part I get data from couchbase :

 var querymain = myBucket.CreateQuery("dev_default", "view_default");
 var result = myBucket.Query<Forum>(querymain);
 foreach (var item in result.Rows.Select(x => x.Value))
            {
                var tempForum = new Forum
                {
                    Id = item.Id,
                    Title = item.Title,
                    Description = item.Description,
                    HasChild = item.HasChild,
                    Level = item.Level,
                    iconPath = item.iconPath,
                    Parent = item.Parent,
                    IsFavorite = item.IsFavorite,
                    TopicCountThisWeek = item.TopicCountThisWeek,
                    MessageCountThisWeek = item.MessageCountThisWeek,
                    RepMode = item.RepMode,
                    ForumExtra = item.ForumExtra
                };
                forums.Add(tempForum);
            }
            return forums;
        }

@andy @jmorris Can you help me on this?


#4

@HandeBc per @andy’s recommendation, your view can return the keys and then you can look up the documents using K/V operations (Get or GetAsync). GetAsync if done with Task.WhenAll(…) will give you the best performance.

You certainly could create additional views for different levels. Additionally, this is where N1QL really shines because you can just create queries with indexes for each grouping.

-Jeff


#5

@jmorris

Hello again, actually there is a solution that I think will solve my problem but I don’t know it is possible to do or how : In my map reduce function, can I take “level” property as a variable ? Like that :

function (doc, meta) {
  
  var key,value;
 	if(doc.type == "mainForums" && doc.level == **VAR**){
   key = [doc.type,doc.id]
   value = {Id : doc.id, Title : doc.title, Description : doc.description, Parent: doc.parent, HasChild : doc.hasChild, Level : doc.level, ImageUrl : "http://icon.donanimhaber.com/mobile-forum-icons/" + doc.iconPath, AvarageColor: doc.avarageColor,  RepMode : doc.repMode, iconPath : doc.iconPath, MessageCountThisWeek : doc.messageCountThisWeek, TopicCountThisWeek : doc.topicCountThisWeek}
                
  emit(key, value);
  }
} 

Since I’m doing this on the couchbase console, I don’t get how I can add variables to this function. I’m doing the mapping part on MVC, to print the json on the screen properly,(as I posted before on 3rd reply) but this map reduce thing, I’m doing on the couchbase console. I should take what mobile(android) programmer gives me as a variable, lets say 4, and bring him level=4 docs from the sync_gateway. Or should android programmer do that map reduce thing?

Also, should I forget about views and use only N1QL on a situation like that? I’m not really sure what is the best and I’m really confused. If my question is not clear, I may send an e-mail or something to who can help.

Thanks a lot.


#6

Anybody? It’s kind of urgent and I’m stuck…