How to automatically get or create a doc with a field value in couchdb in a single request? - mapreduce

In a certain scenario, I want to pass a field value(in string format) to the CouchDB and get associated doc (or only its id) which contains that particular string value in one its fields. In case, if no doc contains that particular field value, I would like CouchDB design functions to automatically create one and return the newly created doc.
I can accomplish this by making a GET request followed by a PUT request if there is no doc with that particular field value. Is there any way to get this done with just one POST request?

Design document functions (other than updates) cannot modify the data in any way.
So no, this is not possible.
You can write a list function to return you a new document if the results are empty, but it cannot save it automatically.

Related

How does Web Source operation's URL Pattern get it's argument when it's assigned a parameter?

when you AutoREST-Enable a table through object browser> click table> REST tab, you will get a RESTful URI. If you then build a web source using that RESTful URI, you will get five operations - GET with a dot as URL pattern and GET, PUT, POST and DELETE operations with URL pattern has the value of :deptno. When you build a report with form on that web source you will find that all database operations work well, you can insert, update and delete through the form, and you can run the report to get all rows in the table. I need to know how the process work in the background? How the automatic row processing process knows which operation and handler to use? I know that Interactive Reports for example looks for the operation that have "Fetch Rows" it's database operation. So, I assumed that the Form's automatic row processing looks up for the Web source's operation with the database operation that relates to the process to be executed. For example, (correct me if I'm wrong) when clicking CREATE button, it denotes that an Insert process will happen, so, it will search for the web source's operation with the database operation "insert row", then it will find the handler that relates to the HTTP method attribute's value "POST". And the same goes for UPDATE and DELETE. I want to know if I am getting it right and I need to know how the URL Pattern gets it's argument for :deptno?
your understanding of the form region picking the Web Source Operation is correct. Within the Form Region, the name of the clicked button (:REQUEST) actually determines the DML operation (CREATE = Insert, SAVE = Update, DELETE = delete).
A :deptno URL parameter must also be created within the Parameters section of the REST data source. Once that is in place, you'll see the form region node in the Page Designer Tree having a Parameters node - there you can map the Web Source Module parameter to a page item, an application item or something else.
As already mentioned, the primary key values are special in a Web Source Module. In your case, the :deptno placeholder (as part of the URL) corresponds to the DEPTNO data profile column.
For the DML handlers (PUT, POST, DELETE) you don't need to define these as Web Source Module parameters, but the URL placeholders must match the column names in the data profile. This is by design - Web Source Modules are implemented to work this way.

django: saving a query set to session

I am trying to save query result obtained in one view to session, and retrieve it in another view, so I tried something like below:
def default (request):
equipment_list = Equipment.objects.all()
request.session['export_querset'] = equipment_list
However, this gives me
TypeError at /calbase/
<QuerySet [<Equipment: A>, <Equipment: B>, <Equipment: C>]> is not JSON serializable
I am wondering what does this mean exactly and how should I go about it? Or maybe there is alternative way of doing what I want besides using session?
If this is what you are saving:
equipment_list = Equipment.objects.all()
You shouldn't or wouldn't need to use sessions. Why? Because this is a simple query without any filtering. equipment_list would be common to all the users. This can quite easily be saved in the cache
from django.core.cache import cache
equipment_list = cache.get('equipment_list')
if not equipment_list:
equipment_list = Equipment.objects.all()
cache.set('equipment_list',equipment_list)
Note that a queryset can be saved in the cache without it having to be converted to values first.
Update:
One of the other answers mention that a querysets are not json serializable. That's only applicable when you are trying to pass that off as a json response. Isn't applicable when you are trying to cache it because django.core.cache does not use json serialization it uses pickling.
'e4c5' raises a concern which is perfectly valid. From the limited code we can see, it makes no sense to put in the results of that query into the session. Unless ofcourse you have some other plans which we cant quite see here. I'll ignore this and assume you ABSOLUTELY MUST save the query results into the session.
With this assumption, you must understand that the queryset instance which Django is giving you is a python object. You can move this around WITHIN your Django application without any hassles. However, whenever you attempt to send such an entity over the wire into some other data store/application (in your case, saving it into the session, which involves sending this data over to your configured session store), it must be serializable to some format which:
your application knows how to serialize objects into
the data store at the other end knows how to de-serialize. In this case, the accepted format seems to be JSON. (this is optional, the JSON string can be stored directly)
The problem is, the queryset instance not only contains the rows returned from the table, it also contains a bunch of other attributes and meta attributes which come in handy to you when you use the Django ORM API. When you try to send the queryset instance over the wire to your session store, the system knows no better and tries to serialize all these attributes into JSON. This fails because there are attributes within the queryset that are not serializable into JSON.
As far as a solution is concerned, if you must save data into the session, as some people have suggested, simply performing objects.all().values() and saving it into your session may not always work. A simple case is when your table returns datetime objects. Datetime objects are by default, not JSON serializable.
So what should you do? What you need is some sort of serializer which accepts a queryset, and safely iterates over the returned rows converting each python native datatype into a JSON safe equivalent, and then returning that. In case of datetime.datetime objects, you would need to call obj.isoformat() to transform it into an ISO format datetime string.
You cannot save a QuerySet instance in session, cause well as you said, they're not JSON Serializable. Read This for more information.
To save your queryset, you can use values and values_list methods to get your desired fields, then you cast them to a list and then save the list into session.(most of the time saving only the PKs does the job though).
so basically:
qset = Model.objects.values_list("pk", "field_one", "field_two") # Gives you a ValuesListQuerySet object which's still not serializable.
cache_results = list(qset)
# Now you cache the cache_results variable however you want.
redis.setex("cached:user_id:querytype", 10 * 60, json.dumps(cache_results))
It's also better to change the way you save this special result (values_list) so you can have better lookups, a dictionary might be a good choice.
Saving query sets in django sessions requires them to be serialized and that causes the error. One way of easily moving the query set by saving them in sessions is to make a list of the id of the Equipments model. (Or any other field that serves as the primary key of the model), like:
equipments = [equipment.id for equipment in Equipment.objects.all()]
request.session['export_querset'] = equipments
And then whenever you need the Equipments, traverse this list and get the corresponding Equipment.
equipments = [Equipment.objects.get(id=id) for id in request.session['export_querset']]
Note: This method is inefficient and is not recommended for large query sets, but for small query sets, it can be used without worries.

Specifying a list fields for searching result in django-haystack

I just wondering is there a way to specify returned fields for search request to the backend elasticsearch. See http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-fields.html for how to specify list in JSON API.
Let me explain why i need this. I have lots of articles with a large text data. Searching in this case is very slow, cause elasticsearch returns a whole large texts for each search results, but i want to render only titles except a whole text.
May be is there another way to do it?
There are multiple options here
You can use the fields option in Elasticsearch to specify the list of fields value that has to be returned. This will save some latency time as only less data has to be transported back. But then actual data would be stored as _source and it has to be fetched from hard disk and deserialized for each call.
LINK - http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-fields.html
In case we don't want to retrieve this field but you just want that field to be searchable. You can disable _source and enable store for each field whose data needs to be retrievable.
LINK , _source - http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-source-field.html
LINK , store - http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/index-modules-store.html
Djanko haystack documentation - http://django-haystack.readthedocs.org/en/latest/searchresult_api.html#SearchResult.get_additional_fields

Find model returns undefined when trying to get the attribute of a model by first finding the model by another attribute?

I would like to do something like:
App.Model.find({unique_attribute_a: 'foo'}).objectAt(0).get('attribute_b')`
basically first finding a model by its unique attribute that is NOT its ID, then getting another attribute of that model. (objectAt(0) is used because find by attribute returns a RecordArray.)
The problem is App.Model.find({unique_attribute_a: 'foo'}).objectAt(0) is always undefined. I don't know why.
Please see the problem in the jsbin.
It looks like you want to use a filter rather than a find (or in this case a findQuery). Example here: http://jsbin.com/iwiruw/438
App.Model.find({ unique_attribute_a: 'foo' }) converts the query to an ajax query string:
/model?unique_attribute_a=foo
Ember data expects your server to return a filtered response. Ember Data then loads this response into an ImmutableArray and makes no assumption about what you were trying to find, it just knows the server returned something that matched your query and groups that result into a non-changable array (you can still modify the record, just not the array).
App.Model.filtler on the other hand just filters the local store based on your filter function. It does have one "magical" side affect where it will do App.Model.find behind the scenes if there are no models in the store although I am not sure if this is intended.
Typically I avoid filters as it can have some performance issues with large data sets and ember data. A filter must materialize every record which can be slow if you have thousands of records
Someone on irc gave me this answer. Then I modified it to make it work completely. Basically I should have used filtered.
App.Office.filter( function(e){return e.get('unique_attribute_a') == 'foo'}).objectAt(0)
Then I can get the attribute like:
App.Office.filter( function(e){return e.get('unique_attribute_a') == 'foo'}).objectAt(0).get('attribute_b')
See the code in jsbin.
Does anyone know WHY filter works but find doesn't? They both return RecordArrays.

Passing n number of input to a GET method of a REST service

I am trying to write a REST service with Jersey where the GET method should write me a list of objects. The input to the GET method should take the ids of the list.
Say I will pass n numbers of EmployeeId and the service should return me a list of employees.
If it is not possible to have #Consumes in the GET method, will there be any problem in using other methods of http like PUT or POST to retrieve the list of objects?
Using POST and PUT for resource retrieval contradicts the conventions established for the usage of REST over HTTP. Switching to either of them just for the sake of using a #Consumes annotation is simply wrong.
If you need to provide additional scoping information for a collection of resources, place it in the URL. Specifically, you can use query parameters. It's a common pattern to implement pagination this way (by providing some limit and offset parameters). Your use case is very similar.
Let's assume this is the URL of a collection of employee resources
GET http://www.example.com/employees
A single employee could be fetched like this:
GET http://www.example.com/employees/id1
If you want to retrieve several employees, you could use a query string like this:
GET http://www.example.com/employees?ids=id1;id3;id8
The identifiers do not need to be delimited by semicolons, this is just an example of a way you could fetch them. Remember that it's treated as a single parameter! You'll have to split the values.
Here's how you could read such a list from the URL above
#Path("employees")
#GET
public Response getEmployees(#QueryParam("ids") String employees){
List<String> ids = Arrays.asList(employes.split(";"));
// Validate the ids, get data from a database,
// prepare a response and return it
}
Parsing the list can be cumbersome, especially if you want to validate the ids somehow. Jersey has a neat feature you can use here. If a class has a single-string-parameter constructor or a SomeType parse(String) method, it can be injected by the framework by parsing the string passed as a parameter (QueryParam, PathParam, FormParam, etc.)
You can take advantage of it to make your resource class cleaner.
#Path("employees")
#GET
public Response getEmployees(#QueryParam("ids") Employees e){
doFancyStaffWithAValidListOfEmployees(e.asList());
//prepare a response
}
Where Employees is a class with a String constructor or a parse method, containing all the splitting and validation logic, possibly even some database queries.
Here's a nice article on writing such parameter classes