Can I query a view using value but not key? - couchdb

I have created a view named doc_view and when i query the view I'm getting results based on view paremeters (like startkey and limit etc)
{"total_rows":103,"rows":[
{"id":"1574031792000.doc","key":"d15836415514","value":{"r":"one"}},
{"id":"1574031832000.doc","key":"d15836418914","value":{"r":"seven"}},
{"id":"14259796657.doc","key":"d1583641`enter code here`8915","value":{"r":"eleven"}},
]
}
Is there any way where I can query the view based on values (that is r field?)

Views can only be queried by key. So you have two options: Write a new view that uses that value you care about as the key, or use a Mango query.

Related

How to run a mango query on a couchdb view?

I use the python package couchdb to access a Apache CouchDB.
My task is to filter documents from the database and be able to select from the filtered database documents with a mango query.
I have defined a view for my database that filters out irrelevant documents. The map function of the view is a sequence of guards (if statements that return nothing if fulfilled). The last statement emits the document with key=id and value=doc:
function(doc) {
if(...) {
return
}
emit(doc._id, doc)
}
Now I want to use a mango query to select some documents from the view.
But the find method does not exist for views. It only exists for the database object:
https://couchdb-python.readthedocs.io/en/latest/client.html#couchdb.client.Database.find
https://couchdb-python.readthedocs.io/en/latest/client.html#couchdb.client.Database.view
Or does it somehow?
And if not, how can I achieve a filter + a mango find with a couchdb?
You cannot perform a mango query on a view. You have to choose between these two options.
A view as you implement is a way to filter and sort documents in a custom order. Then you can fetch these documents by calling the view and get the exact order you defined.
For example, you can specify a specific range of documents to fetch (with the view) by using GET / POST /{db}/_design/{ddoc}/_view/{view} endpoint thanks to its parameters (mainly with startkey, endkey, descending, limit and skip).
But you cannot perform a mango query on a view. Mango queries can only be done on an entire database.
In your case, you probably should use mango query and put indexes on queryable fields to improve performance.

How to query the "Props" table from Flexible Search?

Inside my code I have the primary keys of some page components in Hybris and I have to find all their attributes (properties like title, content etc.)
I can query the "Props" table using an SQL query, but I'm not sure how to find the equivalent in Flexible Search, since querying the database directly is not recommended.
Is there any other simpler way to retrieve all the properties of a component having just the primary key?
What you can do is retrieve the required component using it's primary key. Example:
select {pk} from {SimpleCMSComponent} where {pk} ='8796093056060'
Usually flexible searches are used in DAO classes(Platform example: DefaultProductDao).
When this flexible search is run by the flexible search service you get a ComponentModel. Please see below a groovy script I just created in order to exemplify how to print the ID of a Component retrieved based on its PK(In the same way by using getters you can get the title, content, etc.. ):
import de.hybris.platform.cms2.model.contents.components.SimpleCMSComponentModel;
def flexibleSearchService = spring.getBean("flexibleSearchService");
SimpleCMSComponentModel simpleCmsComponent = flexibleSearchService.search("select {pk} from {SimpleCMSComponent} where {pk} ='8796093056060'").getResult().get(0);
println(simpleCmsComponent.getUid())
I believe though that the best practice in case of CMS Components is to use their IDs instead of PK.

CouchDB views - Multiple join... Can it be done?

I have three document types MainCategory, Category, SubCategory... each have a parentid which relates to the id of their parent document.
So I want to set up a view so that I can get a list of SubCategories which sit under the MainCategory (preferably just using a map function)... I haven't found a way to arrange the view so this is possible.
I currently have set up a view which gets the following output -
{"total_rows":16,"offset":0,"rows":[
{"id":"11098","key":["22056",0,"11098"],"value":"MainCat...."},
{"id":"11098","key":["22056",1,"11098"],"value":"Cat...."},
{"id":"33610","key":["22056",2,"null"],"value":"SubCat...."},
{"id":"33989","key":["22056",2,"null"],"value":"SubCat...."},
{"id":"11810","key":["22245",0,"11810"],"value":"MainCat...."},
{"id":"11810","key":["22245",1,"11810"],"value":"Cat...."},
{"id":"33106","key":["22245",2,"null"],"value":"SubCat...."},
{"id":"33321","key":["22245",2,"null"],"value":"SubCat...."},
{"id":"11098","key":["22479",0,"11098"],"value":"MainCat...."},
{"id":"11098","key":["22479",1,"11098"],"value":"Cat...."},
{"id":"11810","key":["22945",0,"11810"],"value":"MainCat...."},
{"id":"11810","key":["22945",1,"11810"],"value":"Cat...."},
{"id":"33123","key":["22945",2,"null"],"value":"SubCat...."},
{"id":"33453","key":["22945",2,"null"],"value":"SubCat...."},
{"id":"33667","key":["22945",2,"null"],"value":"SubCat...."},
{"id":"33987","key":["22945",2,"null"],"value":"SubCat...."}
]}
Which QueryString parameters would I use to get say the rows which have a key that starts with ["22945".... When all I have (at query time) is the id "11810" (at query time I don't have knowledge of the id "22945").
If any of that makes sense.
Thanks
The way you store your categories seems to be suboptimal for the query you try to perform on it.
MongoDB.org has a page on various strategies to implement tree-structures (they should apply to Couch and other doc dbs as well) - you should consider Array of Ancestors, where you always store the full path to your node. This makes updating/moving categories more difficult, but querying is easy and fast.

CouchDB pagination sorted by date, queried by id

I want to create pagination on application level using the CouchDB view API. The pagination uses cursors, so given a cursor, I will query the view for the n+1 documents starting with the given cursor as start key and output the n results as page and provide the n+1 result row as the cursor for the next page.
This works well as long as the view keys are also the keys for my view rows. Now this time all my docs have a date field and I emit them as map keys, because I want to sort via date. However, I can't use my cursors anymore like before.
I thought that is the reason the view API also provides startkey_docid for submitting such a cursor doc id, however this is obviously not true. It seems like this value is only applied if there are several equal rows per keys.
So, in short: I want a date-ordered view, but cursors based on the document ids. How can I do this?
Thanks in advance
Simplified view
function map(doc)
{
emit(doc.date, {_id: doc._id});
}
Simplified view result:
{
"rows":[
{"id":"123","key":"2010-06-26T01:28:13.555Z", value:{...}},
{"id":"234","key":"2010-06-22T12:21:23.123Z", value:{...}},
{"id":"987","key":"2010-06-16T13:48:43.321Z", value:{...}},
{"id":"103","key":"2010-05-01T17:38:31.123Z", value:{...}},
{"id":"645","key":"2009-07-21T21:21:13.345Z", value:{...}}
]
}
Application-level query with cursor 234, page size 3 should return:
234, 987, 103
So how can I map this to a view?
Why do you want cursors based on docid?
Map Reduce creates single dimensional indexes, so any non-key traversal will be expensive. However, I think you can do what you want without requiring traversing 2 indexes at the same time.
See for instance here how I paginate through a posts with a certain tag:
Sofa's CouchApp tag pagination
aka
http://jchris.couchone.com/sofa/_design/sofa/_list/index/tags?descending=true&reduce=false&limit=10&startkey=[%22life%22%2C{}]&endkey=[%22life%22]
The key in that view looks like ["tag","2008/10/25 04:49:10 +0000"] so you can paginate through by tag and, within tags, by time.
Edited
Ha! I just realized what you are trying to do. It is so very simple.
Forget all about docids, they should be random anyway and not related to anything so just forget docs even have ids for a second.
You say "Application-level query with cursor 234, page size 3 should return:
234, 987, 103"
Your cursor should not be 234. It should be the key "2010-06-22T12:21:23.123Z".
So in essence you use the key of the last row of results as the startkey for the next query. So eg startkey=""2010-06-22T12:21:23.123Z""&limit=3, then for each page you render, link to a query where the new startkey is the last returned key.
Bonus: with what I've just described, you will have the bottom row of page 2 be the top row of page 3. To fix this, add skip=1 to your query.
Bonus bonus: OK, what about when I have more than 3 docs that emitted to the same key in the view? Then the last key will always be the same as the first key, so you can't progress in pagination without expanding the limit parameter. Unless... you use startkey_docid (and set it do the id of the last row). That is the only time you should use startkey_docid.

ExecuteJoinedDataSet but with Where()

I did some searching and see that ExecuteJoinedDataSet will not work with the Where clause in 2.1. If I want to query a table with WHERE, but want the FK objects values to be bindable is the easiest way to just create a custom class(my table has tons of FK references).
Could you give us an example of what kind of query you are trying to write? If you are just trying to return a DataTable without creating a custom class just write your query and use the ExecuteReader which Returns an IDataReader. The IDataReader is bindable and if you need more you can just load it into a DataTable.

Resources