Omi
Omi

Reputation: 1148

couchdb views: return all fields in doc as map

I have a doc in couchDB:

{
"id":"avc",
"type":"Property",
"username":"user1",
"password":"password1",
"server":"localhost"
}

I want to write a view that returns a map of all these fields. The map should look like this: [{"username","user1"},{"password","password1"},{"server","localhost"}]

Here's pseudocode of what I want -

HashMap<String,String> getProperties()
{
    HashMap<String,String> propMap;
    if (doc.type == 'Property')
    {
       //read all fields in doc one by one
       //get value and add field/value to the map
    }
    return propMap;
}

I am not sure how to do the portion that I have commented above. Please help. Note: right now, I want to add username, password and server fields and their values in the map. However, I might keep adding more later on. I want to make sure what I do is extensible.

I considered writing a separate view function for each field. Ex: emit("username",doc.username). But this may not be the best way to do this. Also needs updates every time I add a new field.

Upvotes: 0

Views: 214

Answers (1)

Alexis C&#244;t&#233;
Alexis C&#244;t&#233;

Reputation: 3690

First of all, you have to know:

  1. In CouchDB, you'll index documents inside a view with a key-value pair. So if you index the property username and server, you'll have the following view:
[
  {"key": "user1", "value": null},
  {"key": "localhost", "value": null}
]
  1. Whenever you edit a view, it invalidates the index so Couch has to rebuild the index. If you were to add new fields to that view, that's something you have to take into account.
  2. If you want to query multiple fields in the same query, all those fields must be in the same view. If it's not a requirement, then you could easily build an index for every field you want.

If you want to index multiple fields in the same view, you could do something like this:

// We define a map function as a function which take a single parameter: The document to index.
(doc) => {
  // We iterate over a list of fields to index
  ["username", "password", "server"].forEach((key, value) => {
    // If the document has the field to index, we index it.
    if (doc.hasOwnProperty(key)) {
      // map(key,value) is the function you call to index your document.
      // You don't need to pass a value as you'll be able to get the macthing document by using include_docs=true
      map(doc[key], null);
    }
  });
};

Also, note that Apache Lucene allows to make full-text search and might fit better your needs.

Upvotes: 0

Related Questions