DocumentDB and client side javascript API for querying a collection - azure

I'm playing with DocumentDB's client side javascript API. I want to be able to query a collection. I'd like to use a collection URL, something like:
"https://mydocumentdb.documents.azure.com:9443/dbs/my_db/colls/my_users"
but there appears to be no API function for me to query a documentdb collection without first having the database "self link" and then in turn getting the collections "self link". The only way to get these self links appears to be to first iterate through all my DB's and then pull the right self link, then iterate through my collections, get the collection, finally, use my self link that I got from the service to query the collection.
Really???

Not exactly.
You're correct in that you have to query for a collection's self-link prior to querying the collection. (I know... this can be quite annoying, and is being looked in to by the DocDB team).
However, there is no need to iterate through all of your DB/collections to retrieve self-links as they are indexed server-side.
It is better to query directly for the particular DB/collection you're looking for, which looks something like: client.queryCollections(database._self, 'SELECT * FROM collections c WHERE c.id="' + collectionId + '"'), where collectionId is an identifier you assign.

Related

Cloudant - apply a view/mapReduce to a geospatial query

HI I'm new to cloudant (and couch and asking questions on stackoverflow so I hope I manage to be vaguely clear about what I'm asking ) and I'm trying to do probably the second most basic geo task but am hitting a dead end.
I've got a database of docs which are geojson objects, I've created an index so I can query for intersections etc but it seems the only options I have in the url is the format=legacy (gives me the ids) and the format=geojson and the include_docs parameter - what I'd like to do is give back a particular view of the result set - I'm not interested in the geometry of the object (which is a big lump of data and it's likely that a number of other properties may be in the document that I'd rather filter out)
is there a correct way to do this in a single api call or do I need to fetch the doc ids (legacy format) and then issue a second query to bring back my chosen 'view' for each document id given in the result of format=legacy response
Thanks

Get IDs of nodes via the edge collection only

I am writing an application that stores external data in ArangoDB for further processing inside the application. Let's assume I am talking about Photos in Photosets here.
Due to the nature of used APIs, I need to fetch Photosets befor I can load Photos. In the Photosets API reply, there is a list of Photo IDs that I later use to fetch the Photos. So I created an edge collection called photosInSets and store the edges between Photosets and Photos, although the Photos are not there yet.
Later on, I need to get a list of all needed Photos to load them via the API. All IDs are numeric. At the moment, I use the following AQL query to fetch the IDs of all required Photos:
FOR edge
IN photosInSets
RETURN DISTINCT TO_NUMBER(
SUBSTITUTE(edge._from, "photos/", "")
)
However... this does not look like a nice solution. I'd like to (at least) get rid of the string operation to remove the collection name. What's the nice way to do that?
One way you can find this is with a join on the photosInSets edge collection back to the photos collection.
Try a query that looks like this:
FOR e IN photoInSets
LET item = (FOR v IN photos FILTER e._from == v._id RETURN v._key)
RETURN item
This joins the _from reference in photoInSets with the _id back in the photos collection, then pulls the _key from photos, which won't have the collection name as part of it.
Have a look at a photo item and you'll see there is _id, _key and _rev as system attributes. It's fine to use the _key value if you want a string, it's not necessary to implement your own unique id unless there is a burning reason why you can't expose _key.
With a little manipulation, you could even return an array of objects stating which photo._key is a member of which photoSet, you'll just have to have two LET commands and return both results. One looking at the Photo, one looking at the photoSet.
I'm not official ArangoDB support, but I'm interested if they have another way of doing this.

Algolia Key Value Search

I am currently working with the Algolia search API and I am unable to figure out how I would limit the results by key value searching + query string. By this i mean this.
I have a list of properties.
Each property belongs to a client.
Within the application If i am looking at a client information card and I want to search for a property that client owns It would make more sense to limit the results to the client and then look for the query string.
I am using MongoDB as my DB and storing the client id as a sub document like so
//Property Document
{
_id : "randomID"
client : {
_id : "randomID",
name : "ClientName"
}
}
If you want to restrict the search to a specific client, I would go for facet filtering to restrict the search to that client only.
Add client._id in the attributesForFaceting in your index settings
Filter your searches with the facetFilters=client._id:MYCLIENTID query parameter
Then, you should also take a look at the Secured API keys which are able to encode such restriction in a secure way (so the end-user cannot patch the JS code and work-around the filtering).
There is parameter called restrictSearchableAttributes[link] to restrict, at query time, search to some attributes only. Nevertheless, in your case I think you'd get more accurate results by putting each client info into a different record (+ the info of the related document).

Basic CouchDB Queries

I've never worked with a database before, but I chose Couch DB because I needed a Json database, and HTTP queries seemed kinda simple. However the documentation assumes a level of knowledge I just don't have.
Assuming I have a database called 'subjects', it seems I can access the json by using GET on
http://localhost:5984/subjects/c6604f65029f1a6a5d565da029001f4c
However beyond that I'm stuck. Ideally I want to be able to:
Access a list of all the keys in the database (not their values)
Access an individual element by its key
Do I need to use views for this? Or can I just set fields in my GET request? Can someone give me a complete example of the request they'd use? Please don't link to the CouchDB documentation, it really hasn't helped me so far.
Views can be used to fetch the data
1) In order to get all keys from the database you can use below view
function(doc) {
if (doc.type=="article")
emit(doc._id,null); //emit(key,value), if you have any other field as key then specify as doc.key e.g doc.
}
You can access this view from browser using below URL
http://<ipaddress>:<port>/databasename/_design/designdocumentname/_view/viewname
e.g :
http://<ipaddress>:<port>/article/_design/articlelist/_view/articlelist
article is the database name,articlelist is name of the design document as well as view.
2) In order to access individual document by key
Below view will return all the articles belonging to a particular department
function(doc) {
if(doc.type == 'article' ) {
emit([doc.departmentname], doc);
}
}
Query this view based on the "department name"
e.g: Get all the articles belonging to "IBU3" department
http://<ipaddress>:<port>/department/_design/categoryname/_view/categoryname?key=[%22IBU3%22]

How to bulk fetch by ids in couchdb without creating a view

I need to fetch couchdb documents by a bunch of ids. Is there an request / API to do it ?
I don't want to create a view (id, docs) and then do a find by keys.
when the id b-tree already exists
You should use the bulk API documented here.
It could look something like below.
Pass in the keys as part of the body via a POST
Pass in the name of the db (in the example below, it's demodb)
in the url, use the _all_docs for the view
if you want the entire documents returned (and not just the rev), be sure to pass include_docs=true
curl -d '{"keys":["docId1","docId2","docId3"]}' -X POST http://127.0.0.1:5984/demodb/_all_docs?include_docs=true
If you want to fetch a range of documents, you can also use startkey_docid and limit parameters like you would in a view.
What you do is a GET request to a URL like
http://127.0.0.1:5984/demodb/_all_docs?startkey_docid="docId1"&limit=5
Once you have your set of results, you can use the last returned it as the next startkey and run the request again. This has the benefit of skipping view indexing processes (which can be a pain in the ass for large databases).
Documented in the CouchDB API, here.
If you're using the python-couchdb library, you can use:
_, _, response = <your_db>.resource.post_json('_bulk_get', {'docs': [{'id': '<1st_doc_id>'}, {'id': '<2nd_doc_id>'}]})
Your results will be in response['results'].

Resources