Creating view in Cloudant (CouchDB) based on an object property value

后端 未结 3 1354
心在旅途
心在旅途 2021-01-06 04:21

I\'ve been trying to find a solution for this requirement but I\'ve hit many dead ends.

I\'m using Cloudant as my data store of user documents. Each

相关标签:
3条回答
  • 2021-01-06 04:59

    Cloudant's search works at the granularity of returning a document. Your indexing function could index the categories in use across the items in the document and then your search would return the documents containing items with the category you mention. Your application code would then need to filter down to the items to return to the client.

    Your index function would be something like (shamelessly cribbing from Wintamute):

    if (!doc.items || doc.items.length === 0) return;
    var item;
    for (var i=0; i<doc.items.length; i++) {
      index("cat", doc.items[i].cat, {"index": "not_analyzed"});
    }
    

    The alternative is to break out the items into their own documents if you really want to be able to get just the items.

    However, I'd second (and have up-voted) Wintamute's answer as I agree that the suggested view is the best solution in this specific case (find and display items by cat).

    0 讨论(0)
  • 2021-01-06 05:02

    This actually can be done with Cloudant search. I had a similar issue that I needed to solve. Special thanks to Mike Bresslin at Cloudant for his help.

    function(doc){
        if (doc.items) {
            for (var n in doc.items) {
                if (doc.items[n].cat) {
                   index("cat", doc.items[n].cat, { store : true });
                }
            }
        }
    }
    

    You can query it in a search as:

    ?q=cat:hardwork OR cat:determination
    
    0 讨论(0)
  • 2021-01-06 05:11

    In CouchDB you can't pass in a dynamic value for a query parameter to a view (in your case cat=determination). The approach in CouchDB is to create a more general view, and then adjust how the result is sorted when you call the view to get at the data you need.

    You'll need to create custom view in your db's design document to achieve this:

    byUserItemCat: {
        map: function (doc) {
            if ( !doc.items || doc.items.length === 0 ) return;
            for ( var i=0; i<doc.items.length; i++ ) {
                emit(doc.items[i].cat,{doc._id,doc.items[i].date,doc.items[i].text});
            }
        }
    }
    

    So the above view takes each doc in the db, checks it has an items array with contents, and then loops over all the doc's items. For each item element it finds it emits cat into the result set as the index, this is important since we can then sort against against this index. We're free to build the result object in anyway we like (second argument to emit), and in the above case I'm building an object with the user id, and the item's date and text.

    You'd call the view something like this, to get all the results:

    curl -X GET http://127.0.0.1:5984/<db-name>/_design/<design-doc-name>/_view/byUserItemCat
    

    And if you were just interested in the results where the index key (i.e. cat) was "determination" you'd do:

    curl -X GET http://127.0.0.1:5984/<db-name>/_design/<design-doc-name>/_view/byUserItemCat?key="determination"
    
    0 讨论(0)
提交回复
热议问题