Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CouchDB case in-sensitive and OR options like in mysql

I'm quite new with couchDB and I need a little support.

In MySQL I could run simply this query:

SELECT `name`, `id`, `desc` FROM `table` 
WHERE `name`="jack" OR `cat` LIKE "%|52224|%";

And here are my two problems:

I started to create a view (still without Like option and everything):

function(doc) {
    emit([doc.name, doc.cat], {
"name" : doc.name,
"desc" : doc.desc,
"id" : doc._id
});
}

1. When I use "emit([doc.name" the string must match 100% (also case sensitive).
-> How I make this option case un-sesnsitive?
That I can ask for ("Jack, jack, jAck, JAck,...) like in mysql?

2. How I create the OR option?

When I use [doc.name, doc.cat], I'm also forced to ask for both vars.
But when I have just one of them,
how I can query without creating for each option an own view?

like image 354
heuri Avatar asked Dec 06 '10 14:12

heuri


People also ask

Is like in MySQL case-sensitive?

Mysql ignores case for its LIKE comparisons.

Is like in SQL case-sensitive?

LIKE performs case-insensitive substring matches if the collation for the expression and pattern is case-insensitive.

How do I make MySQL database case-sensitive?

Stop the server, set lower_case_table_names , and restart the server. Reload the dump file for each database. Because lower_case_table_names is set, each database and table name is converted to lowercase as it is recreated: mysql < db1.

How use like with case-insensitive in SQL?

The LIKE statement is used for searching records with partial strings in MySQL. By default the query with LIKE matches case-insensitive recores. Means query will match both records in lowercase or uppercase. For example, Search all records un colors table where name is start with “Gr”.


1 Answers

To implement case insensitive search you just have to convert keys to lowercase:

emit([doc.name.toLowerCase(), doc.cat.toLowerCase()])

Now, if you convert your query to lowercase you'll have case insensitive matching. The problem with this solution is that if you want both case sensitive and case insensitive search you can either emit both values:
[doc.name.toLowerCase(), doc.name, doc.cat]
and use startkey and endkey to filter results, or create a separate view.


The second question is a bit more tricky to implement.
First of all, if you need to filter by doc.name only you can send request with startkey=["jack",0] and endkey=["jack",'zzzzzz'] which will return all documents with doc.name="jack" and doc.cat between 0 and 'zzzzzz' (there probably is a better way to say "any cat", unfortunately I can't find it right now).
If you need a real OR, then you should emit two rows for each document:
emit(doc.name, doc); emit(doc.cat, doc);

This way you can POST needed keys with your request: {"keys": ["jack", "cat_name"]}
This will return every document with either "jack" OR "cat_name" key. However documents that have both will be returned twice, so you have to filter duplicates in your application code.


You can also use couchdb-lucene which will solve both of your problems and probably a lot more. It is a popular choice among couchdb users for implementing advanced queries.

like image 156
allait Avatar answered Sep 23 '22 10:09

allait