code: func (c *InternalClient) ExportCSV(ctx context.Context, index, field string, shard uint64, w io.Writer) error {
  	span, ctx := tracing.StartSpanFromContext(ctx, "InternalClient.ExportCSV")
  	defer span.Finish()
  
  	if index == "" {
  		return pilosa.ErrIndexRequired
  	} else if field == "" {
  		return pilosa.ErrFieldRequired
  	}
  
  	// Retrieve a list of nodes that own the shard.
  	nodes, err := c.FragmentNodes(ctx, index, shard)
  	if err != nil {
  		return fmt.Errorf("shard nodes: %s", err)
  	}
  
  	// Attempt nodes in random order.
  	var e error
  	for _, i := range rand.Perm(len(nodes)) {
  		node := nodes[i]
  
  		if err := c.exportNodeCSV(ctx, node, index, field, shard, w); err != nil {
  			e = fmt.Errorf("export node: host=%s, err=%s", node.URI, err)
  			continue
  		} else {
  			return nil
  		}
  	}
  
  	return e
  }
docs: // ExportCSV bulk exports data for a single shard from a host to CSV format.