有什么方法可以在ouchdb视图中发出附件数据 [英] Is there any way to emit attachment data in a couchdb view

查看:105
本文介绍了有什么方法可以在ouchdb视图中发出附件数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现在网站上图像显示数据时使用CouchDB附件非常有用.但是,当我将数据库复制到移动环境中时,运行视图效率很低,然后不得不循环浏览文档以访问其附件.在iOS/Android平台上,将数据存储为常规BLOBS并仅通过一个视图查询就可以访问所有二进制数据,效率似乎要高得多,该视图查询首先发出所有文档数据.有没有办法在我的地图函数中读取附件数据,并将其包含在emit语句中.我看到有通过_attachments提供的附件信息,但这不能访问数据.

更新 在文档本身而不是附件中使用BLOBS的一个主要缺点(未在接受的答案中进行详细说明)是,当您更新文档时,必须先获取整个文档,然后将其重新发布.如果您不使用附件,则必须获取所有二进制数据,而不必使用附件.如果您要对文档进行更新,那么使用附件确实是设计二进制数据的唯一合理方法.

解决方案

您遇到了一个很棒的问题!

什么是附件?

是二进制数据吗?好的,您可以对数据进行Base64编码并将其直接存储在文档中(类似于数据URI ).而且,您当然可以具有文本或application/json附件.所以不是那样.

是直接下载吗?并不真地. 显示和列出功能使您可以直接提供文档的任何部分(或基于文档数据构建新内容). >

那么附件是什么?对我来说,附件的有效定义是在视图,显示和列表中不可访问的数据.这是一个优化.您无法通过服务器端Javascript访问它;但是,由于CouchDB不必对大量数据进行编码和解码,因此您可以提高速度.

有时我也像C指针一样考虑它.使用指针非常快.它们是小的,简单的数据类型.但是,代价是额外的编程工作,因为必须取消引用它们才能获取数据.您总是有一个额外的步骤.那就是速度的代价. CouchDB附件是相似的.

如果您的数据很小(也许是图标,电子名片,文本)并且适合整个文档,那就去吧!不要附上它们.但是,对于较大的数据(例如大多数图像和其他文件),必须添加附件.

多次提取

假设您查询一个视图并获得20行以在屏幕上显示.现在,您必须获取20个图像附件.

程序员本能地发现这是不受欢迎的.而且,是的,这可能会破坏交易.但是,在许多情况下,这是一个很好的权衡.唐纳德·克努斯(Donald Knuth)说:过早的优化是万恶之源."由SSD支持的本地服务器总共进行21次访存会杀死我们吗?

在许多情况下,进行20个查询就可以了.关键是要同时制作它们. CouchDB(和移动Couchbase)针对并发请求进行了优化.您会发现,获取20张图像所需的时间基本上与获取一张图像所需的时间相同.

同时获取HTTP资源在每种语言中的工作方式都不同.在Javascript中,非常非常容易,需要使用 async.js 的几行代码.

// Assuming fetch_image(), and images = ['alice.png', 'bob.png',  etc.]
async.forEach(images, fetch_image, function(er) {
  if(er) throw er
  console.log('Fetched 20 images!')
})

I have found it very useful to use CouchDB attachments when image displaying data on a website. However when I replicate the database to a mobile environment, it's very inefficient to run a view and then have to cycle through the documents to get access to their attachments. On the iOS/Android platform it seems a lot more efficient to store the data as regular BLOBS and have access to all binary data with just one view query, the view query that emits all the document data in the first place. Is there a way to read attachment DATA in my map function, and include it in the emit statement. I see that there is attachment information available via _attachments, but this does not give access to the data.

Update A major drawback (not detailed in the accepted answer) to using BLOBS in in the document itself rather than attachments is that when you update a document you have to GET the entire document and then POST it back. If you aren't using attachments you have to get all that binary data, with attachments you don't. If you will be performing updates on your documents, using attachments is really the only reasonable way to design for binary data.

解决方案

You've hit upon a great question!

What is an attachment?

Is it binary data? Well, you can Base64 encode data and store it directly in the document (similar to a data URI). And you can of course have text or application/json attachments. So it's not that.

Is it direct downloads? Not really. Show and list functions let you serve any part of the document directly (or build new content based on document data).

So what is an attachment? To me, a working definition of attachments is, data which is not accessible in views, shows, and lists. It is an optimization. You lose access to it from server-side Javascript; however you gain speed because CouchDB doesn't have to encode and decode a huge amount of data.

Sometimes I also think about it like C pointers. Working with pointers is very fast. They are a small, simple data type. However, the cost is extra programming work, because they must be dereferenced to get to the data. You always have an extra step. That is the cost of the speed. CouchDB attachments are similar.

If your data is small (maybe favicons, vcards, text) and fits in the entire document, go for it! Don't attach them. However for larger data such as most images and other files, attachments become necessary.

Multiple fetches

Suppose you query a view and get 20 rows for display on the screen. Now you must fetch 20 image attachments.

Programmers instinctively find this undesirable. And, yes, it might be a deal-breaker. However in many cases it's a fine trade-off. Donald Knuth says, "premature optimization is the root of all evil." Will it kill us to make 21 total fetches from a local server, backed by SSD?

In many cases, it is just fine to make 20 queries. The key is to make them all at the same time. CouchDB (and mobile couchbase) is optimized for concurrent requests. You will find that fetching 20 images takes basically the same time as fetching one.

Fetching an HTTP resource concurrently works differently in every language. In Javascript, it is very easy, requiring a few lines of code with async.js.

// Assuming fetch_image(), and images = ['alice.png', 'bob.png',  etc.]
async.forEach(images, fetch_image, function(er) {
  if(er) throw er
  console.log('Fetched 20 images!')
})

这篇关于有什么方法可以在ouchdb视图中发出附件数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆