CouchDB中的多键搜索
给定以下对象结构:CouchDB中的多键搜索,couchdb,Couchdb,给定以下对象结构: { key1: "...", key2: "...", data: "..." } 有没有办法通过查询key1和key2而不设置两个不同的视图(每个键一个)从CouchDB获取此对象,如: 亲切问候,, 阿乔姆 编辑: 以下是对问题的更好描述: 上面描述的对象是一个序列化的游戏状态。一个游戏只有一个创建者用户(键1)和他的对手(键2)。对于一个给定的用户,我希望获得他参与的所有游戏(作为创建者和对手)。您可以创建一个CouchDB视图,该视图生成如下输出:
{
key1: "...",
key2: "...",
data: "..."
}
有没有办法通过查询key1和key2而不设置两个不同的视图(每个键一个)从CouchDB获取此对象,如:
亲切问候,,
阿乔姆
编辑:
以下是对问题的更好描述:
上面描述的对象是一个序列化的游戏状态。一个游戏只有一个创建者用户(键1)和他的对手(键2)。对于一个给定的用户,我希望获得他参与的所有游戏(作为创建者和对手)。您可以创建一个CouchDB视图,该视图生成如下输出:
["key1", 111],
["key1", 123],
["key2", 111],
["key2", 123],
etc.
用javascript编写地图视图非常简单:
function(doc) {
emit(["key1", doc["key1"]], null);
emit(["key2", doc["key2"]], null);
}
查询时,可以使用多个键进行查询:
{"keys": [["key1", 123], ["key2", 123]]}
您可以将JSON作为POST中的数据发送到视图。或者最好为您的编程语言使用API。此查询的结果将是视图中与任一键匹配的每一行。因此,在key1和key2上匹配的每个文档都将在视图结果中返回两行。发出两个键(如果相等,则仅发出一个键):
使用(正确的url编码)进行查询:
或具有多个值:
?include_docs=true&keys=[123,567,...]
更新:更新为通过一次查询查询多个值。我将其用于一个web服务,该web服务查询我的所有文档,并返回与存在的节点和查询匹配的所有文档。在本例中,我使用节点“detail”进行搜索。如果要搜索其他节点,则需要指定 这是我的第一篇堆栈溢出帖子,所以我希望我能帮助别人:)
***Python代码
导入tornado.httpserver
导入tornado.ioloop
导入tornado.options
导入tornado.web
导入httplib,json
从tornado.options导入,定义选项
定义(“端口”,默认值=8000,help=“在给定端口上运行”,type=int)
类MainHandler(tornado.web.RequestHandler):
def get(自我):
db\u host='您的\u COUCHDB\u服务器'
db_端口=5984
数据库名称='您的数据库'
node=self.get_参数('node',无)
query=self.get\u参数('query',None)
清除=无
如果节点else self.write('您尚未提供对象节点。
'),则清除=1
cleared=2 if query else self.write('您尚未提供查询字符串。
')
如果清除为2:
uri=''.join(['/',db_name'/','.\u design/keysearch/'+node+'/?startkey=“'+query+'”&endkey=“'+query+'\u9999”]”)
connection=httplib.HTTPConnection(db\u主机,db\u端口)
headers={“Accept”:“application/json”}
请求(“GET”、uri、None、headers)
response=connection.getresponse()
write(json.dumps(json.load(response.read()),sort_keys=True,indent=4))
类应用程序(tornado.web.Application):
定义初始化(自):
处理程序=[
(r“/”,主处理器)
]
设置=听写(
调试=真
)
tornado.web.Application.\uuuuu init\uuuuuuu(self,handlers,**设置)
def main():
tornado.options.parse_命令行()
http_server=tornado.httpserver.httpserver(应用程序())
http_server.listen(options.port)
tornado.ioloop.ioloop.instance().start()
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()
***CouchDB设计视图
{
“\u id”:“\u设计/键搜索”,
“语言”:“javascript”,
“意见”:{
“细节”:{
“映射”:“函数(doc){var docs=doc['detail'].match(/[A-Za-z0-9]+/g);if(docs){for(var-each-in-docs){emit(docs[each],doc);}}”
}
}
}
我也在努力解决一个类似的问题,即如何使用
"select * from ... where key1=123 or key2=123".
以下视图允许您按LastName或FirstName字段查找客户文档:
function(doc) {
if (doc.Type == "customer") {
emit(doc.LastName, {FirstName: doc.FirstName, Address: doc.Address});
emit(doc.FirstName, {LastName: doc.LastName, Address: doc.Address});
}
}
欢迎加入。你可以通过点击下方的“编辑”链接按钮来编辑你自己的文章以添加相关信息。您应该这样做,并在信息出现在您的答案中后删除您的评论:)祝您好运,有关更多信息,请查看我们的帮助部分:
?include_docs=true&keys=[123,567,...]
***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); } } }"
}
}
}
"select * from ... where key1=123 or key2=123".
function(doc) {
if (doc.Type == "customer") {
emit(doc.LastName, {FirstName: doc.FirstName, Address: doc.Address});
emit(doc.FirstName, {LastName: doc.LastName, Address: doc.Address});
}
}