HowTo use Client Java API for Searching inside Documents
Hi,
I have used in the past only SQL Databases but I'm very interested in NoSQL and want to use it for a new project.
I read the wiki/manual and tried a few example programs, but the main big problem I have is to understand how to implement a "search" with the Java API.
For example: My data consists of "customers" and "orders". Each customer can have multiple orders. Now I want to write a Java Client program with a search field and search button. When pressing the button the result should depend on the search field content. E.g. searching for "name" and "address" fields inside the customer document.
1. Is there a way to do it on the server side?
2. Or should I write a view document containing all customers fields for searching and doing the filtering on client side.?
3. How do I access a view from the Java API
4. Do I need the new Couchbase2.0 server or is it also possible to do it with the stable 1.8 version?
5. Is it better to create one document containing the "customer" data and all "orders" together or is it better to put only a reference to the orders inside the customer document?
Thank you for your help!
Thank you for your answers and offered help!
I set up a testing environment on my computer with Couchbase 2.0 and using the Java Client 1.1DP now.
First I want to report my successfully work to get all orders for a customer with the help of a view.
For this, I have created some sample "customers" and "orders" documents based on the following structure:
{
"_id": "customer.docid.customer1",
"_rev": "5-f5e6e0abdc99eb820000005700000000",
"$flags": 0,
"$expiration": 0,
"firstName": "John",
"lastName": "Mayer",
"Street": "Wall Street 4",
"type": "customer"
}
{
"_id": "order.order1",
"_rev": "3-5d6c0a1c22b00ef50000004f00000000",
"$flags": 0,
"$expiration": 0,
"customerID": "customer.docid.customer1",
"quantity": 50,
"price": 100,
"type": "order"
}First I started to get all Orders for a single Customer. For this I created a new View with the following map-function:
function (doc) {
if(doc.type=="order")
{
emit(doc.customerID, doc._id);
}
}It is now possible to get all the orders of a customer by setting the query-key of the java client library to the customerId.
... query.setKey("customer.docid.customer1"); ... View view = client.getView("dev_lf", "OrdersList"); ... ViewResponse result = client.query(view, query); ... Iterator<ViewRow> itr = result.iterator(); ...
Now I am very happy with this result and I hope this was what you meant.
For the second step (the customer search) I have still understanding problems. I can create a new view for this with a special key which contains all possible search fields:
function (doc) {
if(doc.type=="customer")
{
emit(doc.firstName + " " + doc.lastName, doc._id);
}
}My problem is now, how to to query on client side, if I only know a part of my key and how can I ignore upper/lower case key search.
In other words my customer view result looks like this now:
|key |value | |--------------------|--------------------------| |firstname1 lastname1|"customer.docid.customer1"| |John Mayer |"customer.docid.customer2"| |Bob Mayer |"customer.docid.customer3"| |Steve Mueller |"customer.docid.customer4"|
How can I query for the two customers with the lastname "Mayer" or for all customers which lastname begins with an "m"? Is this possible or do I have to process this step on client side?
If you're only searching by last name, I would emit only the last name, which you could emit it as a particular case:
function (doc) { if(doc.type=="customer") { emit(doc.lastName.toLowerCase(), null); } }
That way when you search, you could specify the starting and ending key as always lower case (this might not be the right API for the Java client, I'm only a little familiar with that client).
query.setStartKey("m"); query.setEndKey("n");
To get both Mayers in the datbase:
query.setKey("mayer");
If you would like to get first name and last name, you could use a composite key:
function (doc) { if(doc.type=="customer") { emit([doc.lastName.toLower(), doc.firstName], null); } }
-- John
1. Yes, you can do this server side through views. What you will want to do is write a map reduce view through the Couchbase Web UI to filter the data properly. If you are new to map-reduce then let me know and I can help guide you through writing a view.
2. I think your confused here on what a view is. Creating a view on the server side builds an index with the documents in Couchbase. This index can be queried by our Couchbase SDK's in a similar way to what you would do in a relational database. Note though that you cannot use SQL and must use a syntax very similar to how you would get a document using CouchDB.
3. The latest Java SDK for Couchbase 2.0 is the Couchbase Java Client 1.1DP. This client will provide some functions for obtaining a reference to a view and querying that view. Those functions can be found in the CouchbaseClient class.
4. Views are only available in Couchbase 2.0.
5. Both of the ways you suggest here can be done without a view. For example if you know the customers name and the document key is the customer id then if you could map customer names to customer id's then could get a customers data with one get operation in the first case. In the second case you would do a get on the customer and then gets on all of the orders.
If you want to create a view you could have separate order and customer documents. The order documents would contain the customer name and you would build a view that indexed all of the orders. You could then query that view to return all of the orders that contain the customers name.
Let me know if you have any other questions.