Search for multiple keywords in CouchDB

Given the following structure of the object:

{ key1: "...", key2: "...", data: "..." } 

Is there a way to get this object from CouchDB by querying both key1 and key2 without setting up two different views (one for each key), for example:

 select * from ... where key1=123 or key2=123 

Regards, Artjom

change

Here is the best description of the problem: The object described above is a serialized game state. The game has exactly one creator user (key1) and his opponent (key2). For this user, I would like to get all the games in which he participates (both the creator and the opponent).

+6
source share
4 answers

Extract both keys (or only one if they are equal):

 function(doc) { if (doc.hasOwnProperty('key1')) { emit(doc.key1, 1); } if (doc.hasOwnProperty('key2') && doc.key1 !== doc.key2) { emit(doc.key2, 1); } } 

Request with (correctly encoded by URL):

 ?include_docs=true&key=123 

or with multiple values:

 ?include_docs=true&keys=[123,567,...] 

UPDATE: Updated to query multiple values ​​with a single query.

+4
source

You can create a CouchDB view that produces output, for example:

 ["key1", 111], ["key1", 123], ["key2", 111], ["key2", 123], etc. 

It is very simple to write a map view in javascript:

 function(doc) { emit(["key1", doc["key1"]], null); emit(["key2", doc["key2"]], null); } 

When prompted, you can request a few keys:

 {"keys": [["key1", 123], ["key2", 123]]} 

You can send this JSON as data in POST for submission. Or it is advisable to use an API for your programming language. The result of this query will be each row in the view corresponding to any key. Thus, each document that matches both key1 and key2 will return two rows in the view results.

+2
source

I also struggled with a simulated question of how to use

 "select * from ... where key1=123 or key2=123". 

The following view allows you to search for client documents by LastName or FirstName fields:

 function(doc) { if (doc.Type == "customer") { emit(doc.LastName, {FirstName: doc.FirstName, Address: doc.Address}); emit(doc.FirstName, {LastName: doc.LastName, Address: doc.Address}); } } 

I found the answer above: https://wiki.apache.org/couchdb/Introduction_to_CouchDB_views#Map_Functions

+1
source

I use this for a web service that requests all my documents and returns every document that matches both the existence of the node and the request. In this example, I use node 'detail' to search. If you want to find another node, you need to specify.

This is my first post, so I hope I can help someone :)

 ***Python Code import tornado.httpserver import tornado.ioloop import tornado.options import tornado.web import httplib, json from tornado.options import define,options define("port", default=8000, help="run on the given port", type=int) class MainHandler(tornado.web.RequestHandler): def get(self): db_host = 'YOUR_COUCHDB_SERVER' db_port = 5984 db_name = 'YOUR_COUCHDB_DATABASE' node = self.get_argument('node',None) query = self.get_argument('query',None) cleared = None cleared = 1 if node else self.write('You have not supplied an object node.<br>') cleared = 2 if query else self.write('You have not supplied a query string.<br>') if cleared is 2: uri = ''.join(['/', db_name, '/', '_design/keysearch/_view/' + node + '/?startkey="' + query + '"&endkey="' + query + '\u9999"']) connection = httplib.HTTPConnection(db_host, db_port) headers = {"Accept": "application/json"} connection.request("GET", uri, None, headers) response = connection.getresponse() self.write(json.dumps(json.loads(response.read()), sort_keys=True, indent=4)) class Application(tornado.web.Application): def __init__(self): handlers = [ (r"/", MainHandler) ] settings = dict( debug = True ) tornado.web.Application.__init__(self, handlers, **settings) def main(): tornado.options.parse_command_line() http_server = tornado.httpserver.HTTPServer(Application()) http_server.listen(options.port) tornado.ioloop.IOLoop.instance().start() if __name__ == '__main__': main() ***CouchDB Design View { "_id": "_design/keysearch", "language": "javascript", "views": { "detail": { "map": "function(doc) { var docs = doc['detail'].match(/[A-Za-z0-9]+/g); if(docs) { for(var each in docs) { emit(docs[each],doc); } } }" } } } 
0
source

Source: https://habr.com/ru/post/917031/


All Articles